diff --git a/src/ImageSharp/ImageFrame{TPixel}.cs b/src/ImageSharp/ImageFrame{TPixel}.cs index be1792ced1..ecf9e13ceb 100644 --- a/src/ImageSharp/ImageFrame{TPixel}.cs +++ b/src/ImageSharp/ImageFrame{TPixel}.cs @@ -2,8 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; -using System.Buffers; -using System.Numerics; using System.Runtime.CompilerServices; using System.Threading.Tasks; using SixLabors.ImageSharp.Advanced; @@ -289,22 +287,16 @@ namespace SixLabors.ImageSharp var target = new ImageFrame(configuration, this.Width, this.Height, this.MetaData.DeepClone()); - ParallelHelper.IterateRowsWithTempBuffer( + ParallelHelper.IterateRows( this.Bounds(), configuration, - (rows, tempRowBuffer) => + (rows) => { for (int y = rows.Min; y < rows.Max; y++) { Span sourceRow = this.GetPixelRowSpan(y); Span targetRow = target.GetPixelRowSpan(y); - Span tempRowSpan = tempRowBuffer.Span; - - PixelOperations.Instance.ToScaledVector4(sourceRow, tempRowSpan, sourceRow.Length); - PixelOperations.Instance.PackFromScaledVector4( - tempRowSpan, - targetRow, - targetRow.Length); + PixelOperations.Instance.To(sourceRow, targetRow, sourceRow.Length); } }); diff --git a/src/ImageSharp/ImageSharp.csproj b/src/ImageSharp/ImageSharp.csproj index a7ca0a014c..7eec03cb6a 100644 --- a/src/ImageSharp/ImageSharp.csproj +++ b/src/ImageSharp/ImageSharp.csproj @@ -76,10 +76,42 @@ TextTemplatingFileGenerator PixelOperations{TPixel}.Generated.cs + + TextTemplatingFileGenerator + Argb32.PixelOperations.Generated.cs + + + TextTemplatingFileGenerator + Bgr24.PixelOperations.Generated.cs + + + TextTemplatingFileGenerator + Bgra32.PixelOperations.Generated.cs + + + TextTemplatingFileGenerator + Gray8.PixelOperations.Generated.cs + + + TextTemplatingFileGenerator + Gray16.PixelOperations.Generated.cs + + + TextTemplatingFileGenerator + Rgb24.PixelOperations.Generated.cs + TextTemplatingFileGenerator Rgba32.PixelOperations.Generated.cs + + TextTemplatingFileGenerator + Rgb48.PixelOperations.Generated.cs + + + TextTemplatingFileGenerator + Rgba64.PixelOperations.Generated.cs + PorterDuffFunctions.Generated.cs TextTemplatingFileGenerator @@ -110,11 +142,51 @@ True PixelOperations{TPixel}.Generated.tt + + True + True + Argb32.PixelOperations.Generated.tt + + + True + True + Bgr24.PixelOperations.Generated.tt + + + True + True + Bgra32.PixelOperations.Generated.tt + + + True + True + Gray8.PixelOperations.Generated.tt + + + True + True + Gray16.PixelOperations.Generated.tt + + + True + True + Rgb24.PixelOperations.Generated.tt + True True Rgba32.PixelOperations.Generated.tt + + True + True + Rgb48.PixelOperations.Generated.tt + + + True + True + Rgba64.PixelOperations.Generated.tt + True True diff --git a/src/ImageSharp/PixelFormats/Alpha8.cs b/src/ImageSharp/PixelFormats/Alpha8.cs index 063200c69e..1e724768d0 100644 --- a/src/ImageSharp/PixelFormats/Alpha8.cs +++ b/src/ImageSharp/PixelFormats/Alpha8.cs @@ -79,6 +79,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackedValue = source.A; + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackedValue = byte.MaxValue; + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackedValue = source.A; @@ -91,6 +95,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackedValue = byte.MaxValue; + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackedValue = byte.MaxValue; + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackedValue = source.A; diff --git a/src/ImageSharp/PixelFormats/Argb32.cs b/src/ImageSharp/PixelFormats/Argb32.cs index 0da8516a3e..1e3bd93262 100644 --- a/src/ImageSharp/PixelFormats/Argb32.cs +++ b/src/ImageSharp/PixelFormats/Argb32.cs @@ -19,7 +19,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// as it avoids the need to create new values for modification operations. /// [StructLayout(LayoutKind.Sequential)] - public struct Argb32 : IPixel, IPackedVector + public partial struct Argb32 : IPixel, IPackedVector { /// /// Gets or sets the alpha component. @@ -165,7 +165,7 @@ namespace SixLabors.ImageSharp.PixelFormats public static bool operator !=(Argb32 left, Argb32 right) => !left.Equals(right); /// - public PixelOperations CreatePixelOperations() => new PixelOperations(); + public PixelOperations CreatePixelOperations() => new PixelOperations(); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -187,6 +187,16 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackedValue = source.PackedValue; + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) + { + this.R = source.R; + this.G = source.G; + this.B = source.B; + this.A = byte.MaxValue; + } + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) @@ -218,6 +228,16 @@ namespace SixLabors.ImageSharp.PixelFormats this.A = byte.MaxValue; } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) + { + this.R = source.R; + this.G = source.G; + this.B = source.B; + this.A = byte.MaxValue; + } + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) @@ -269,13 +289,6 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() => this.Argb.GetHashCode(); - /// - /// Gets the representation without normalizing to [0, 1] - /// - /// A of values in [0, 255] - [MethodImpl(InliningOptions.ShortMethod)] - internal Vector4 ToByteScaledVector4() => new Vector4(this.R, this.G, this.B, this.A); - /// /// Packs the four floats into a color. /// diff --git a/src/ImageSharp/PixelFormats/Bgr24.cs b/src/ImageSharp/PixelFormats/Bgr24.cs index 063fed5221..ed65bebf7f 100644 --- a/src/ImageSharp/PixelFormats/Bgr24.cs +++ b/src/ImageSharp/PixelFormats/Bgr24.cs @@ -15,7 +15,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// [StructLayout(LayoutKind.Explicit)] - public struct Bgr24 : IPixel + public partial struct Bgr24 : IPixel { /// /// The blue component. @@ -72,7 +72,7 @@ namespace SixLabors.ImageSharp.PixelFormats public static bool operator !=(Bgr24 left, Bgr24 right) => !left.Equals(right); /// - public PixelOperations CreatePixelOperations() => new PixelOperations(); + public PixelOperations CreatePixelOperations() => new PixelOperations(); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -104,6 +104,10 @@ namespace SixLabors.ImageSharp.PixelFormats this.B = source.B; } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this = source; + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) @@ -132,6 +136,15 @@ namespace SixLabors.ImageSharp.PixelFormats this.B = rgb; } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) + { + this.R = source.R; + this.G = source.G; + this.B = source.B; + } + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this = source.Bgr; diff --git a/src/ImageSharp/PixelFormats/Bgr565.cs b/src/ImageSharp/PixelFormats/Bgr565.cs index 5b19fb25c1..454f458b12 100644 --- a/src/ImageSharp/PixelFormats/Bgr565.cs +++ b/src/ImageSharp/PixelFormats/Bgr565.cs @@ -87,6 +87,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackFromVector4(source.ToVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackFromVector4(source.ToVector4()); @@ -99,6 +103,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromVector4(source.ToVector4()); diff --git a/src/ImageSharp/PixelFormats/Bgra32.cs b/src/ImageSharp/PixelFormats/Bgra32.cs index 6fd0867797..9b0ed4f96d 100644 --- a/src/ImageSharp/PixelFormats/Bgra32.cs +++ b/src/ImageSharp/PixelFormats/Bgra32.cs @@ -16,7 +16,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// [StructLayout(LayoutKind.Sequential)] - public struct Bgra32 : IPixel, IPackedVector + public partial struct Bgra32 : IPixel, IPackedVector { /// /// Gets or sets the blue component. @@ -121,7 +121,7 @@ namespace SixLabors.ImageSharp.PixelFormats public static bool operator !=(Bgra32 left, Bgra32 right) => !left.Equals(right); /// - public PixelOperations CreatePixelOperations() => new PixelOperations(); + public PixelOperations CreatePixelOperations() => new PixelOperations(); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -151,7 +151,17 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this.PackedValue = source.PackedValue; + public void PackFromBgr24(Bgr24 source) + { + this.R = source.R; + this.G = source.G; + this.B = source.B; + this.A = byte.MaxValue; + } + + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgra32(Bgra32 source) => this = source; /// [MethodImpl(InliningOptions.ShortMethod)] @@ -184,6 +194,16 @@ namespace SixLabors.ImageSharp.PixelFormats this.A = source.A; } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) + { + this.R = source.R; + this.G = source.G; + this.B = source.B; + this.A = byte.MaxValue; + } + /// [MethodImpl(InliningOptions.ShortMethod)] public Rgba32 ToRgba32() => new Rgba32(this.R, this.G, this.B, this.A); @@ -220,13 +240,6 @@ namespace SixLabors.ImageSharp.PixelFormats /// public override string ToString() => $"Bgra32({this.B}, {this.G}, {this.R}, {this.A})"; - /// - /// Gets the representation without normalizing to [0, 1] - /// - /// A of values in [0, 255] - [MethodImpl(InliningOptions.ShortMethod)] - internal Vector4 ToByteScaledVector4() => new Vector4(this.R, this.G, this.B, this.A); - /// /// Packs a into a color. /// diff --git a/src/ImageSharp/PixelFormats/Bgra4444.cs b/src/ImageSharp/PixelFormats/Bgra4444.cs index 8a5e3f76b3..08484eba8d 100644 --- a/src/ImageSharp/PixelFormats/Bgra4444.cs +++ b/src/ImageSharp/PixelFormats/Bgra4444.cs @@ -90,6 +90,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -102,6 +106,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/Bgra5551.cs b/src/ImageSharp/PixelFormats/Bgra5551.cs index 25f289b846..df0a467301 100644 --- a/src/ImageSharp/PixelFormats/Bgra5551.cs +++ b/src/ImageSharp/PixelFormats/Bgra5551.cs @@ -91,6 +91,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -103,6 +107,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -147,8 +155,5 @@ namespace SixLabors.ImageSharp.PixelFormats | (((int)Math.Round(vector.Z * 31F) & 0x1F) << 0) | (((int)Math.Round(vector.W) & 0x1) << 15)); } - - [MethodImpl(InliningOptions.ShortMethod)] - private Vector4 ToByteScaledVector4() => this.ToVector4() * 255F; } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Byte4.cs b/src/ImageSharp/PixelFormats/Byte4.cs index fbdf4862db..34546e0271 100644 --- a/src/ImageSharp/PixelFormats/Byte4.cs +++ b/src/ImageSharp/PixelFormats/Byte4.cs @@ -89,11 +89,15 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromArgb32(Argb32 source) => this.PackFromVector4(source.ToByteScaledVector4()); + public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this.PackFromVector4(source.ToByteScaledVector4()); + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -103,6 +107,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/Generated/Argb32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/Generated/Argb32.PixelOperations.Generated.cs new file mode 100644 index 0000000000..0b40df8dae --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Argb32.PixelOperations.Generated.cs @@ -0,0 +1,177 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Argb32 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromArgb32(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + + /// + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromArgb32(sp); + } + } + + /// + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgra32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromArgb32(sp); + } + } + + /// + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray8 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray8 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromArgb32(sp); + } + } + + /// + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray16 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray16 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromArgb32(sp); + } + } + + /// + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromArgb32(sp); + } + } + + /// + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromArgb32(sp); + } + } + + /// + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb48 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromArgb32(sp); + } + } + + /// + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba64 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromArgb32(sp); + } + } + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Argb32.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/Generated/Argb32.PixelOperations.Generated.tt new file mode 100644 index 0000000000..f35adee022 --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Argb32.PixelOperations.Generated.tt @@ -0,0 +1,85 @@ +<# +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. +#> +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + void GenerateConvertToMethod(string pixelType) + { + #> + + /// + internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Argb32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); + ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromArgb32(sp); + } + } + <# + } +#> +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Argb32 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromArgb32(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + <# + GenerateConvertToMethod("Bgr24"); + GenerateConvertToMethod("Bgra32"); + GenerateConvertToMethod("Gray8"); + GenerateConvertToMethod("Gray16"); + GenerateConvertToMethod("Rgb24"); + GenerateConvertToMethod("Rgba32"); + GenerateConvertToMethod("Rgb48"); + GenerateConvertToMethod("Rgba64"); + #> + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Bgr24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/Generated/Bgr24.PixelOperations.Generated.cs new file mode 100644 index 0000000000..e895254576 --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Bgr24.PixelOperations.Generated.cs @@ -0,0 +1,177 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Bgr24 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromBgr24(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + + /// + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Argb32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Argb32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgr24(sp); + } + } + + /// + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgra32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgr24(sp); + } + } + + /// + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray8 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray8 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgr24(sp); + } + } + + /// + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray16 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray16 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgr24(sp); + } + } + + /// + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgr24(sp); + } + } + + /// + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgr24(sp); + } + } + + /// + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb48 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgr24(sp); + } + } + + /// + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba64 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgr24(sp); + } + } + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Bgr24.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/Generated/Bgr24.PixelOperations.Generated.tt new file mode 100644 index 0000000000..76163549b0 --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Bgr24.PixelOperations.Generated.tt @@ -0,0 +1,85 @@ +<# +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. +#> +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + void GenerateConvertToMethod(string pixelType) + { + #> + + /// + internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); + ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgr24(sp); + } + } + <# + } +#> +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Bgr24 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromBgr24(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + <# + GenerateConvertToMethod("Argb32"); + GenerateConvertToMethod("Bgra32"); + GenerateConvertToMethod("Gray8"); + GenerateConvertToMethod("Gray16"); + GenerateConvertToMethod("Rgb24"); + GenerateConvertToMethod("Rgba32"); + GenerateConvertToMethod("Rgb48"); + GenerateConvertToMethod("Rgba64"); + #> + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Bgra32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/Generated/Bgra32.PixelOperations.Generated.cs new file mode 100644 index 0000000000..2311e0bde6 --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Bgra32.PixelOperations.Generated.cs @@ -0,0 +1,177 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Bgra32 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromBgra32(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + + /// + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Argb32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Argb32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgra32(sp); + } + } + + /// + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgra32(sp); + } + } + + /// + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray8 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray8 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgra32(sp); + } + } + + /// + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray16 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray16 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgra32(sp); + } + } + + /// + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgra32(sp); + } + } + + /// + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgra32(sp); + } + } + + /// + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb48 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgra32(sp); + } + } + + /// + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba64 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgra32(sp); + } + } + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Bgra32.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/Generated/Bgra32.PixelOperations.Generated.tt new file mode 100644 index 0000000000..4c2925d18f --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Bgra32.PixelOperations.Generated.tt @@ -0,0 +1,85 @@ +<# +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. +#> +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + void GenerateConvertToMethod(string pixelType) + { + #> + + /// + internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); + ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromBgra32(sp); + } + } + <# + } +#> +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Bgra32 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromBgra32(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + <# + GenerateConvertToMethod("Argb32"); + GenerateConvertToMethod("Bgr24"); + GenerateConvertToMethod("Gray8"); + GenerateConvertToMethod("Gray16"); + GenerateConvertToMethod("Rgb24"); + GenerateConvertToMethod("Rgba32"); + GenerateConvertToMethod("Rgb48"); + GenerateConvertToMethod("Rgba64"); + #> + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Gray16.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/Generated/Gray16.PixelOperations.Generated.cs new file mode 100644 index 0000000000..a2d9aa755f --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Gray16.PixelOperations.Generated.cs @@ -0,0 +1,177 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Gray16 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromGray16(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + + /// + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Argb32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); + ref Argb32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray16(sp); + } + } + + /// + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray16(sp); + } + } + + /// + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgra32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray16(sp); + } + } + + /// + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray8 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray8 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray16(sp); + } + } + + /// + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray16(sp); + } + } + + /// + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray16(sp); + } + } + + /// + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb48 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray16(sp); + } + } + + /// + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba64 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray16(sp); + } + } + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Gray16.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/Generated/Gray16.PixelOperations.Generated.tt new file mode 100644 index 0000000000..b900e343a7 --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Gray16.PixelOperations.Generated.tt @@ -0,0 +1,85 @@ +<# +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. +#> +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + void GenerateConvertToMethod(string pixelType) + { + #> + + /// + internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray16 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray16 sp = ref Unsafe.Add(ref sourceRef, i); + ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray16(sp); + } + } + <# + } +#> +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Gray16 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromGray16(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + <# + GenerateConvertToMethod("Argb32"); + GenerateConvertToMethod("Bgr24"); + GenerateConvertToMethod("Bgra32"); + GenerateConvertToMethod("Gray8"); + GenerateConvertToMethod("Rgb24"); + GenerateConvertToMethod("Rgba32"); + GenerateConvertToMethod("Rgb48"); + GenerateConvertToMethod("Rgba64"); + #> + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Gray8.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/Generated/Gray8.PixelOperations.Generated.cs new file mode 100644 index 0000000000..de2c11d4d9 --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Gray8.PixelOperations.Generated.cs @@ -0,0 +1,177 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Gray8 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromGray8(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + + /// + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Argb32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); + ref Argb32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray8(sp); + } + } + + /// + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray8(sp); + } + } + + /// + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgra32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray8(sp); + } + } + + /// + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray16 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray16 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray8(sp); + } + } + + /// + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray8(sp); + } + } + + /// + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray8(sp); + } + } + + /// + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb48 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray8(sp); + } + } + + /// + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba64 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray8(sp); + } + } + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Gray8.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/Generated/Gray8.PixelOperations.Generated.tt new file mode 100644 index 0000000000..4590420e57 --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Gray8.PixelOperations.Generated.tt @@ -0,0 +1,85 @@ +<# +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. +#> +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + void GenerateConvertToMethod(string pixelType) + { + #> + + /// + internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Gray8 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Gray8 sp = ref Unsafe.Add(ref sourceRef, i); + ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromGray8(sp); + } + } + <# + } +#> +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Gray8 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromGray8(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + <# + GenerateConvertToMethod("Argb32"); + GenerateConvertToMethod("Bgr24"); + GenerateConvertToMethod("Bgra32"); + GenerateConvertToMethod("Gray16"); + GenerateConvertToMethod("Rgb24"); + GenerateConvertToMethod("Rgba32"); + GenerateConvertToMethod("Rgb48"); + GenerateConvertToMethod("Rgba64"); + #> + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs index 852ff73e0e..66966543fc 100644 --- a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs +++ b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs @@ -11,633 +11,633 @@ namespace SixLabors.ImageSharp.PixelFormats public partial class PixelOperations { /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts 'count' elements in 'source` span of data to a span of -s. /// - /// The source of data. + /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFromRgba64(ReadOnlySpan source, Span destPixels, int count) + internal virtual void PackFromArgb32(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(source); - ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); - - // For conversion methods writing only to RGB channels, we need to keep the alpha channel opaque! - var temp = NamedColors.Black; + ref Argb32 sourceBaseRef = ref MemoryMarshal.GetReference(source); + ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref TPixel dp = ref Unsafe.Add(ref destRef, i); - temp = Unsafe.Add(ref sourceRef, i); - dp.PackFromRgba64(temp); + ref Argb32 sp = ref Unsafe.Add(ref sourceBaseRef, i); + ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); + + dp.PackFromArgb32(sp); } } /// - /// A helper for that expects a byte span. - /// The layout of the data in 'sourceBytes' must be compatible with layout. + /// A helper for that expects a byte span. + /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFromRgba64Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void PackFromArgb32Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFromRgba64(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.PackFromArgb32(MemoryMarshal.Cast(sourceBytes), destPixels, count); } + /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// /// The span of source pixels - /// The destination span of data. + /// The destination span of data. /// The number of pixels to convert. - internal virtual void ToRgba64(ReadOnlySpan sourcePixels, Span dest, int count) + internal virtual void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Rgba64 destBaseRef = ref MemoryMarshal.GetReference(dest); + ref Argb32 destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); - ref Rgba64 dp = ref Unsafe.Add(ref destBaseRef, i); + ref Argb32 dp = ref Unsafe.Add(ref destBaseRef, i); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } /// - /// A helper for that expects a byte span as destination. - /// The layout of the data in 'destBytes' must be compatible with layout. + /// A helper for that expects a byte span as destination. + /// The layout of the data in 'destBytes' must be compatible with layout. /// - /// The to the source colors. + /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void ToRgba64Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) + internal void ToArgb32Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToRgba64(sourceColors, MemoryMarshal.Cast(destBytes), count); + this.ToArgb32(sourcePixels, MemoryMarshal.Cast(destBytes), count); } /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts 'count' elements in 'source` span of data to a span of -s. /// - /// The source of data. + /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFromRgb48(ReadOnlySpan source, Span destPixels, int count) + internal virtual void PackFromBgr24(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(source); - ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); - - // For conversion methods writing only to RGB channels, we need to keep the alpha channel opaque! - var temp = NamedColors.Black; + ref Bgr24 sourceBaseRef = ref MemoryMarshal.GetReference(source); + ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref TPixel dp = ref Unsafe.Add(ref destRef, i); - temp = Unsafe.Add(ref sourceRef, i); - dp.PackFromRgb48(temp); + ref Bgr24 sp = ref Unsafe.Add(ref sourceBaseRef, i); + ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); + + dp.PackFromBgr24(sp); } } /// - /// A helper for that expects a byte span. - /// The layout of the data in 'sourceBytes' must be compatible with layout. + /// A helper for that expects a byte span. + /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFromRgb48Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void PackFromBgr24Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFromRgb48(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.PackFromBgr24(MemoryMarshal.Cast(sourceBytes), destPixels, count); } + /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// /// The span of source pixels - /// The destination span of data. + /// The destination span of data. /// The number of pixels to convert. - internal virtual void ToRgb48(ReadOnlySpan sourcePixels, Span dest, int count) + internal virtual void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Rgb48 destBaseRef = ref MemoryMarshal.GetReference(dest); + ref Bgr24 destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); - ref Rgb48 dp = ref Unsafe.Add(ref destBaseRef, i); + ref Bgr24 dp = ref Unsafe.Add(ref destBaseRef, i); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } /// - /// A helper for that expects a byte span as destination. - /// The layout of the data in 'destBytes' must be compatible with layout. + /// A helper for that expects a byte span as destination. + /// The layout of the data in 'destBytes' must be compatible with layout. /// - /// The to the source colors. + /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void ToRgb48Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) + internal void ToBgr24Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToRgb48(sourceColors, MemoryMarshal.Cast(destBytes), count); + this.ToBgr24(sourcePixels, MemoryMarshal.Cast(destBytes), count); } /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts 'count' elements in 'source` span of data to a span of -s. /// - /// The source of data. + /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFromRgba32(ReadOnlySpan source, Span destPixels, int count) + internal virtual void PackFromBgra32(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(source); - ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); - - // For conversion methods writing only to RGB channels, we need to keep the alpha channel opaque! - var temp = NamedColors.Black; + ref Bgra32 sourceBaseRef = ref MemoryMarshal.GetReference(source); + ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref TPixel dp = ref Unsafe.Add(ref destRef, i); - temp = Unsafe.Add(ref sourceRef, i); - dp.PackFromRgba32(temp); + ref Bgra32 sp = ref Unsafe.Add(ref sourceBaseRef, i); + ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); + + dp.PackFromBgra32(sp); } } /// - /// A helper for that expects a byte span. - /// The layout of the data in 'sourceBytes' must be compatible with layout. + /// A helper for that expects a byte span. + /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFromRgba32Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void PackFromBgra32Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFromRgba32(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.PackFromBgra32(MemoryMarshal.Cast(sourceBytes), destPixels, count); } + /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// /// The span of source pixels - /// The destination span of data. + /// The destination span of data. /// The number of pixels to convert. - internal virtual void ToRgba32(ReadOnlySpan sourcePixels, Span dest, int count) + internal virtual void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Rgba32 destBaseRef = ref MemoryMarshal.GetReference(dest); + ref Bgra32 destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); - ref Rgba32 dp = ref Unsafe.Add(ref destBaseRef, i); + ref Bgra32 dp = ref Unsafe.Add(ref destBaseRef, i); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } /// - /// A helper for that expects a byte span as destination. - /// The layout of the data in 'destBytes' must be compatible with layout. + /// A helper for that expects a byte span as destination. + /// The layout of the data in 'destBytes' must be compatible with layout. /// - /// The to the source colors. + /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void ToRgba32Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) + internal void ToBgra32Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToRgba32(sourceColors, MemoryMarshal.Cast(destBytes), count); + this.ToBgra32(sourcePixels, MemoryMarshal.Cast(destBytes), count); } /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts 'count' elements in 'source` span of data to a span of -s. /// - /// The source of data. + /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFromBgra32(ReadOnlySpan source, Span destPixels, int count) + internal virtual void PackFromGray8(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(source); - ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); - - // For conversion methods writing only to RGB channels, we need to keep the alpha channel opaque! - var temp = NamedColors.Black; + ref Gray8 sourceBaseRef = ref MemoryMarshal.GetReference(source); + ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref TPixel dp = ref Unsafe.Add(ref destRef, i); - temp = Unsafe.Add(ref sourceRef, i); - dp.PackFromBgra32(temp); + ref Gray8 sp = ref Unsafe.Add(ref sourceBaseRef, i); + ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); + + dp.PackFromGray8(sp); } } /// - /// A helper for that expects a byte span. - /// The layout of the data in 'sourceBytes' must be compatible with layout. + /// A helper for that expects a byte span. + /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFromBgra32Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void PackFromGray8Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFromBgra32(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.PackFromGray8(MemoryMarshal.Cast(sourceBytes), destPixels, count); } + /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// /// The span of source pixels - /// The destination span of data. + /// The destination span of data. /// The number of pixels to convert. - internal virtual void ToBgra32(ReadOnlySpan sourcePixels, Span dest, int count) + internal virtual void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Bgra32 destBaseRef = ref MemoryMarshal.GetReference(dest); + ref Gray8 destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); - ref Bgra32 dp = ref Unsafe.Add(ref destBaseRef, i); + ref Gray8 dp = ref Unsafe.Add(ref destBaseRef, i); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } /// - /// A helper for that expects a byte span as destination. - /// The layout of the data in 'destBytes' must be compatible with layout. + /// A helper for that expects a byte span as destination. + /// The layout of the data in 'destBytes' must be compatible with layout. /// - /// The to the source colors. + /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void ToBgra32Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) + internal void ToGray8Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToBgra32(sourceColors, MemoryMarshal.Cast(destBytes), count); + this.ToGray8(sourcePixels, MemoryMarshal.Cast(destBytes), count); } /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts 'count' elements in 'source` span of data to a span of -s. /// - /// The source of data. + /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFromRgb24(ReadOnlySpan source, Span destPixels, int count) + internal virtual void PackFromGray16(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(source); - ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); - - // For conversion methods writing only to RGB channels, we need to keep the alpha channel opaque! - var temp = NamedColors.Black; + ref Gray16 sourceBaseRef = ref MemoryMarshal.GetReference(source); + ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref TPixel dp = ref Unsafe.Add(ref destRef, i); - temp.Rgb = Unsafe.Add(ref sourceRef, i); - dp.PackFromRgba32(temp); + ref Gray16 sp = ref Unsafe.Add(ref sourceBaseRef, i); + ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); + + dp.PackFromGray16(sp); } } /// - /// A helper for that expects a byte span. - /// The layout of the data in 'sourceBytes' must be compatible with layout. + /// A helper for that expects a byte span. + /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFromRgb24Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void PackFromGray16Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFromRgb24(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.PackFromGray16(MemoryMarshal.Cast(sourceBytes), destPixels, count); } + /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// /// The span of source pixels - /// The destination span of data. + /// The destination span of data. /// The number of pixels to convert. - internal virtual void ToRgb24(ReadOnlySpan sourcePixels, Span dest, int count) + internal virtual void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Rgb24 destBaseRef = ref MemoryMarshal.GetReference(dest); + ref Gray16 destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); - ref Rgb24 dp = ref Unsafe.Add(ref destBaseRef, i); + ref Gray16 dp = ref Unsafe.Add(ref destBaseRef, i); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } /// - /// A helper for that expects a byte span as destination. - /// The layout of the data in 'destBytes' must be compatible with layout. + /// A helper for that expects a byte span as destination. + /// The layout of the data in 'destBytes' must be compatible with layout. /// - /// The to the source colors. + /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void ToRgb24Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) + internal void ToGray16Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToRgb24(sourceColors, MemoryMarshal.Cast(destBytes), count); + this.ToGray16(sourcePixels, MemoryMarshal.Cast(destBytes), count); } /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts 'count' elements in 'source` span of data to a span of -s. /// - /// The source of data. + /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFromBgr24(ReadOnlySpan source, Span destPixels, int count) + internal virtual void PackFromRgb24(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(source); - ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); - - // For conversion methods writing only to RGB channels, we need to keep the alpha channel opaque! - var temp = NamedColors.Black; + ref Rgb24 sourceBaseRef = ref MemoryMarshal.GetReference(source); + ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref TPixel dp = ref Unsafe.Add(ref destRef, i); - temp.Bgr = Unsafe.Add(ref sourceRef, i); - dp.PackFromRgba32(temp); + ref Rgb24 sp = ref Unsafe.Add(ref sourceBaseRef, i); + ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); + + dp.PackFromRgb24(sp); } } /// - /// A helper for that expects a byte span. - /// The layout of the data in 'sourceBytes' must be compatible with layout. + /// A helper for that expects a byte span. + /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFromBgr24Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void PackFromRgb24Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFromBgr24(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.PackFromRgb24(MemoryMarshal.Cast(sourceBytes), destPixels, count); } + /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// /// The span of source pixels - /// The destination span of data. + /// The destination span of data. /// The number of pixels to convert. - internal virtual void ToBgr24(ReadOnlySpan sourcePixels, Span dest, int count) + internal virtual void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Bgr24 destBaseRef = ref MemoryMarshal.GetReference(dest); + ref Rgb24 destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); - ref Bgr24 dp = ref Unsafe.Add(ref destBaseRef, i); + ref Rgb24 dp = ref Unsafe.Add(ref destBaseRef, i); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } /// - /// A helper for that expects a byte span as destination. - /// The layout of the data in 'destBytes' must be compatible with layout. + /// A helper for that expects a byte span as destination. + /// The layout of the data in 'destBytes' must be compatible with layout. /// - /// The to the source colors. + /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void ToBgr24Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) + internal void ToRgb24Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToBgr24(sourceColors, MemoryMarshal.Cast(destBytes), count); + this.ToRgb24(sourcePixels, MemoryMarshal.Cast(destBytes), count); } /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts 'count' elements in 'source` span of data to a span of -s. /// - /// The source of data. + /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFromArgb32(ReadOnlySpan source, Span destPixels, int count) + internal virtual void PackFromRgba32(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref Argb32 sourceRef = ref MemoryMarshal.GetReference(source); - ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); - - // For conversion methods writing only to RGB channels, we need to keep the alpha channel opaque! - var temp = NamedColors.Black; + ref Rgba32 sourceBaseRef = ref MemoryMarshal.GetReference(source); + ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref TPixel dp = ref Unsafe.Add(ref destRef, i); - temp = Unsafe.Add(ref sourceRef, i); - dp.PackFromArgb32(temp); + ref Rgba32 sp = ref Unsafe.Add(ref sourceBaseRef, i); + ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); + + dp.PackFromRgba32(sp); } } /// - /// A helper for that expects a byte span. - /// The layout of the data in 'sourceBytes' must be compatible with layout. + /// A helper for that expects a byte span. + /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFromArgb32Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void PackFromRgba32Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFromArgb32(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.PackFromRgba32(MemoryMarshal.Cast(sourceBytes), destPixels, count); } + /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// /// The span of source pixels - /// The destination span of data. + /// The destination span of data. /// The number of pixels to convert. - internal virtual void ToArgb32(ReadOnlySpan sourcePixels, Span dest, int count) + internal virtual void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Argb32 destBaseRef = ref MemoryMarshal.GetReference(dest); + ref Rgba32 destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); - ref Argb32 dp = ref Unsafe.Add(ref destBaseRef, i); + ref Rgba32 dp = ref Unsafe.Add(ref destBaseRef, i); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } /// - /// A helper for that expects a byte span as destination. - /// The layout of the data in 'destBytes' must be compatible with layout. + /// A helper for that expects a byte span as destination. + /// The layout of the data in 'destBytes' must be compatible with layout. /// - /// The to the source colors. + /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void ToArgb32Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) + internal void ToRgba32Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToArgb32(sourceColors, MemoryMarshal.Cast(destBytes), count); + this.ToRgba32(sourcePixels, MemoryMarshal.Cast(destBytes), count); } /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts 'count' elements in 'source` span of data to a span of -s. /// - /// The source of data. + /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFromGray8(ReadOnlySpan source, Span destPixels, int count) + internal virtual void PackFromRgb48(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref Gray8 sourceRef = ref MemoryMarshal.GetReference(source); - ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); - - // For conversion methods writing only to RGB channels, we need to keep the alpha channel opaque! - var temp = NamedColors.Black; + ref Rgb48 sourceBaseRef = ref MemoryMarshal.GetReference(source); + ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref TPixel dp = ref Unsafe.Add(ref destRef, i); - temp = Unsafe.Add(ref sourceRef, i); - dp.PackFromGray8(temp); + ref Rgb48 sp = ref Unsafe.Add(ref sourceBaseRef, i); + ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); + + dp.PackFromRgb48(sp); } } /// - /// A helper for that expects a byte span. - /// The layout of the data in 'sourceBytes' must be compatible with layout. + /// A helper for that expects a byte span. + /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFromGray8Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void PackFromRgb48Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFromGray8(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.PackFromRgb48(MemoryMarshal.Cast(sourceBytes), destPixels, count); } + /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// /// The span of source pixels - /// The destination span of data. + /// The destination span of data. /// The number of pixels to convert. - internal virtual void ToGray8(ReadOnlySpan sourcePixels, Span dest, int count) + internal virtual void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Gray8 destBaseRef = ref MemoryMarshal.GetReference(dest); + ref Rgb48 destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); - ref Gray8 dp = ref Unsafe.Add(ref destBaseRef, i); + ref Rgb48 dp = ref Unsafe.Add(ref destBaseRef, i); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } /// - /// A helper for that expects a byte span as destination. - /// The layout of the data in 'destBytes' must be compatible with layout. + /// A helper for that expects a byte span as destination. + /// The layout of the data in 'destBytes' must be compatible with layout. /// - /// The to the source colors. + /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void ToGray8Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) + internal void ToRgb48Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToGray8(sourceColors, MemoryMarshal.Cast(destBytes), count); + this.ToRgb48(sourcePixels, MemoryMarshal.Cast(destBytes), count); } /// - /// Converts 'count' elements in 'source` span of data to a span of -s. + /// Converts 'count' elements in 'source` span of data to a span of -s. /// - /// The source of data. + /// The source of data. /// The to the destination pixels. /// The number of pixels to convert. - internal virtual void PackFromGray16(ReadOnlySpan source, Span destPixels, int count) + internal virtual void PackFromRgba64(ReadOnlySpan source, Span destPixels, int count) { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref Gray16 sourceRef = ref MemoryMarshal.GetReference(source); - ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); - - // For conversion methods writing only to RGB channels, we need to keep the alpha channel opaque! - var temp = NamedColors.Black; + ref Rgba64 sourceBaseRef = ref MemoryMarshal.GetReference(source); + ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref TPixel dp = ref Unsafe.Add(ref destRef, i); - temp = Unsafe.Add(ref sourceRef, i); - dp.PackFromGray16(temp); + ref Rgba64 sp = ref Unsafe.Add(ref sourceBaseRef, i); + ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); + + dp.PackFromRgba64(sp); } } /// - /// A helper for that expects a byte span. - /// The layout of the data in 'sourceBytes' must be compatible with layout. + /// A helper for that expects a byte span. + /// The layout of the data in 'sourceBytes' must be compatible with layout. /// /// The to the source bytes. /// The to the destination pixels. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void PackFromGray16Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) + internal void PackFromRgba64Bytes(ReadOnlySpan sourceBytes, Span destPixels, int count) { - this.PackFromGray16(MemoryMarshal.Cast(sourceBytes), destPixels, count); + this.PackFromRgba64(MemoryMarshal.Cast(sourceBytes), destPixels, count); } + /// - /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. + /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// /// The span of source pixels - /// The destination span of data. + /// The destination span of data. /// The number of pixels to convert. - internal virtual void ToGray16(ReadOnlySpan sourcePixels, Span dest, int count) + internal virtual void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Gray16 destBaseRef = ref MemoryMarshal.GetReference(dest); + ref Rgba64 destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); - ref Gray16 dp = ref Unsafe.Add(ref destBaseRef, i); + ref Rgba64 dp = ref Unsafe.Add(ref destBaseRef, i); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } /// - /// A helper for that expects a byte span as destination. - /// The layout of the data in 'destBytes' must be compatible with layout. + /// A helper for that expects a byte span as destination. + /// The layout of the data in 'destBytes' must be compatible with layout. /// - /// The to the source colors. + /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void ToGray16Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) + internal void ToRgba64Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.ToGray16(sourceColors, MemoryMarshal.Cast(destBytes), count); + this.ToRgba64(sourcePixels, MemoryMarshal.Cast(destBytes), count); } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt index 9fbe57ed9b..913dabb087 100644 --- a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt +++ b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt @@ -11,7 +11,7 @@ <#@ output extension=".cs" #> <# - void GeneratePackFromMethods(string pixelType, string tempPixelType, string assignToTempCode) + void GeneratePackFromMethods(string pixelType) { #> @@ -25,17 +25,15 @@ { GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - ref <#=pixelType#> sourceRef = ref MemoryMarshal.GetReference(source); - ref TPixel destRef = ref MemoryMarshal.GetReference(destPixels); - - // For conversion methods writing only to RGB channels, we need to keep the alpha channel opaque! - var temp = NamedColors<<#=tempPixelType#>>.Black; + ref <#=pixelType#> sourceBaseRef = ref MemoryMarshal.GetReference(source); + ref TPixel destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref TPixel dp = ref Unsafe.Add(ref destRef, i); - <#=assignToTempCode#> - dp.PackFrom<#=tempPixelType#>(temp); + ref <#=pixelType#> sp = ref Unsafe.Add(ref sourceBaseRef, i); + ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i); + + dp.PackFrom<#=pixelType#>(sp); } } @@ -51,6 +49,7 @@ { this.PackFrom<#=pixelType#>(MemoryMarshal.Cast>(sourceBytes), destPixels, count); } + <# } @@ -61,19 +60,20 @@ /// Converts 'count' pixels in 'sourcePixels` span to a span of -s. /// /// The span of source pixels - /// The destination span of data. + /// The destination span of data. /// The number of pixels to convert. - internal virtual void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> dest, int count) + internal virtual void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref TPixel sourceBaseRef = ref MemoryMarshal.GetReference(sourcePixels); - ref <#=pixelType#> destBaseRef = ref MemoryMarshal.GetReference(dest); + ref <#=pixelType#> destBaseRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i); ref <#=pixelType#> dp = ref Unsafe.Add(ref destBaseRef, i); + dp.PackFromScaledVector4(sp.ToScaledVector4()); } } @@ -82,13 +82,13 @@ /// A helper for that expects a byte span as destination. /// The layout of the data in 'destBytes' must be compatible with layout. /// - /// The to the source colors. + /// The to the source pixels. /// The to the destination bytes. /// The number of pixels to convert. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void To<#=pixelType#>Bytes(ReadOnlySpan sourceColors, Span destBytes, int count) + internal void To<#=pixelType#>Bytes(ReadOnlySpan sourcePixels, Span destBytes, int count) { - this.To<#=pixelType#>(sourceColors, MemoryMarshal.Cast>(destBytes), count); + this.To<#=pixelType#>(sourcePixels, MemoryMarshal.Cast>(destBytes), count); } <# } @@ -107,32 +107,32 @@ namespace SixLabors.ImageSharp.PixelFormats public partial class PixelOperations {<# - GeneratePackFromMethods("Rgba64", "Rgba64", "temp = Unsafe.Add(ref sourceRef, i);"); - GenerateToDestFormatMethods("Rgba64"); - - GeneratePackFromMethods("Rgb48", "Rgb48", "temp = Unsafe.Add(ref sourceRef, i);"); - GenerateToDestFormatMethods("Rgb48"); - - GeneratePackFromMethods("Rgba32", "Rgba32", "temp = Unsafe.Add(ref sourceRef, i);"); - GenerateToDestFormatMethods("Rgba32"); - - GeneratePackFromMethods("Bgra32", "Bgra32", "temp = Unsafe.Add(ref sourceRef, i);"); - GenerateToDestFormatMethods("Bgra32"); - - GeneratePackFromMethods("Rgb24", "Rgba32", "temp.Rgb = Unsafe.Add(ref sourceRef, i);"); - GenerateToDestFormatMethods("Rgb24"); + GeneratePackFromMethods("Argb32"); + GenerateToDestFormatMethods("Argb32"); - GeneratePackFromMethods("Bgr24", "Rgba32", "temp.Bgr = Unsafe.Add(ref sourceRef, i);"); + GeneratePackFromMethods("Bgr24"); GenerateToDestFormatMethods("Bgr24"); - GeneratePackFromMethods("Argb32", "Argb32", "temp = Unsafe.Add(ref sourceRef, i);"); - GenerateToDestFormatMethods("Argb32"); + GeneratePackFromMethods("Bgra32"); + GenerateToDestFormatMethods("Bgra32"); - GeneratePackFromMethods("Gray8", "Gray8", "temp = Unsafe.Add(ref sourceRef, i);"); + GeneratePackFromMethods("Gray8"); GenerateToDestFormatMethods("Gray8"); - GeneratePackFromMethods("Gray16", "Gray16", "temp = Unsafe.Add(ref sourceRef, i);"); + GeneratePackFromMethods("Gray16"); GenerateToDestFormatMethods("Gray16"); + GeneratePackFromMethods("Rgb24"); + GenerateToDestFormatMethods("Rgb24"); + + GeneratePackFromMethods("Rgba32"); + GenerateToDestFormatMethods("Rgba32"); + + GeneratePackFromMethods("Rgb48"); + GenerateToDestFormatMethods("Rgb48"); + + GeneratePackFromMethods("Rgba64"); + GenerateToDestFormatMethods("Rgba64"); + #> } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Rgb24.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/Generated/Rgb24.PixelOperations.Generated.cs new file mode 100644 index 0000000000..ad4ee2764e --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Rgb24.PixelOperations.Generated.cs @@ -0,0 +1,177 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Rgb24 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromRgb24(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + + /// + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Argb32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Argb32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb24(sp); + } + } + + /// + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb24(sp); + } + } + + /// + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgra32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb24(sp); + } + } + + /// + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray8 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray8 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb24(sp); + } + } + + /// + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray16 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray16 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb24(sp); + } + } + + /// + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb24(sp); + } + } + + /// + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb48 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb24(sp); + } + } + + /// + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba64 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb24(sp); + } + } + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Rgb24.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/Generated/Rgb24.PixelOperations.Generated.tt new file mode 100644 index 0000000000..6a10b401f4 --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Rgb24.PixelOperations.Generated.tt @@ -0,0 +1,85 @@ +<# +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. +#> +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + void GenerateConvertToMethod(string pixelType) + { + #> + + /// + internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); + ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb24(sp); + } + } + <# + } +#> +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Rgb24 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromRgb24(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + <# + GenerateConvertToMethod("Argb32"); + GenerateConvertToMethod("Bgr24"); + GenerateConvertToMethod("Bgra32"); + GenerateConvertToMethod("Gray8"); + GenerateConvertToMethod("Gray16"); + GenerateConvertToMethod("Rgba32"); + GenerateConvertToMethod("Rgb48"); + GenerateConvertToMethod("Rgba64"); + #> + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Rgb48.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/Generated/Rgb48.PixelOperations.Generated.cs new file mode 100644 index 0000000000..0a1ef03873 --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Rgb48.PixelOperations.Generated.cs @@ -0,0 +1,177 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Rgb48 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromRgb48(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + + /// + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Argb32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); + ref Argb32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb48(sp); + } + } + + /// + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb48(sp); + } + } + + /// + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgra32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb48(sp); + } + } + + /// + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray8 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray8 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb48(sp); + } + } + + /// + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray16 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray16 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb48(sp); + } + } + + /// + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb48(sp); + } + } + + /// + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb48(sp); + } + } + + /// + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba64 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb48(sp); + } + } + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Rgb48.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/Generated/Rgb48.PixelOperations.Generated.tt new file mode 100644 index 0000000000..e38c85bf62 --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Rgb48.PixelOperations.Generated.tt @@ -0,0 +1,85 @@ +<# +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. +#> +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + void GenerateConvertToMethod(string pixelType) + { + #> + + /// + internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgb48 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgb48 sp = ref Unsafe.Add(ref sourceRef, i); + ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgb48(sp); + } + } + <# + } +#> +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Rgb48 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromRgb48(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + <# + GenerateConvertToMethod("Argb32"); + GenerateConvertToMethod("Bgr24"); + GenerateConvertToMethod("Bgra32"); + GenerateConvertToMethod("Gray8"); + GenerateConvertToMethod("Gray16"); + GenerateConvertToMethod("Rgb24"); + GenerateConvertToMethod("Rgba32"); + GenerateConvertToMethod("Rgba64"); + #> + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs index 9621505952..bd3e014b4d 100644 --- a/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs +++ b/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs @@ -13,133 +13,161 @@ namespace SixLabors.ImageSharp.PixelFormats /// public partial struct Rgba32 { + + /// + /// Provides optimized overrides for bulk operations. + /// internal partial class PixelOperations { + /// + internal override void PackFromRgba32(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + /// - internal override void PackFromRgb24(ReadOnlySpan source, Span destPixels, int count) + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - ref Rgb24 sourceRef = ref MemoryMarshal.GetReference(source); - ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); + ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Argb32 destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i); - ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); - Unsafe.As(ref dp) = sp; dp.A = byte.MaxValue; + ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Argb32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba32(sp); } } /// - internal override void ToRgb24(ReadOnlySpan sourcePixels, Span dest, int count) + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Rgb24 destRef = ref MemoryMarshal.GetReference(dest); + ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); - ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); - dp = Unsafe.As(ref sp); + ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba32(sp); } } /// - internal override void PackFromBgr24(ReadOnlySpan source, Span destPixels, int count) + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - ref Bgr24 sourceRef = ref MemoryMarshal.GetReference(source); - ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); + ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgra32 destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i); - ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); - dp.Bgr = sp; dp.A = byte.MaxValue; + ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba32(sp); } } /// - internal override void ToBgr24(ReadOnlySpan sourcePixels, Span dest, int count) + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Bgr24 destRef = ref MemoryMarshal.GetReference(dest); + ref Gray8 destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); - ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); - dp = sp.Bgr; + ref Gray8 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba32(sp); } } /// - internal override void PackFromBgra32(ReadOnlySpan source, Span destPixels, int count) + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - ref Bgra32 sourceRef = ref MemoryMarshal.GetReference(source); - ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); + ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray16 destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i); - ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); - dp.R = sp.R; dp.G = sp.G; dp.B = sp.B; dp.A = sp.A; + ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray16 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba32(sp); } } /// - internal override void ToBgra32(ReadOnlySpan sourcePixels, Span dest, int count) + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Bgra32 destRef = ref MemoryMarshal.GetReference(dest); + ref Rgb24 destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); - ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); + ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); + dp.PackFromRgba32(sp); } } /// - internal override void PackFromArgb32(ReadOnlySpan source, Span destPixels, int count) + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - ref Argb32 sourceRef = ref MemoryMarshal.GetReference(source); - ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); + ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb48 destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { - ref Argb32 sp = ref Unsafe.Add(ref sourceRef, i); - ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); - dp.R = sp.R; dp.G = sp.G; dp.B = sp.B; dp.A = sp.A; + ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba32(sp); } } /// - internal override void ToArgb32(ReadOnlySpan sourcePixels, Span dest, int count) + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref Argb32 destRef = ref MemoryMarshal.GetReference(dest); + ref Rgba64 destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); - ref Argb32 dp = ref Unsafe.Add(ref destRef, i); + ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); + dp.PackFromRgba32(sp); } } diff --git a/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.tt index 9d9145f0b9..23d0be740e 100644 --- a/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.tt +++ b/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.tt @@ -9,45 +9,24 @@ <#@ import namespace="System.Collections.Generic" #> <#@ output extension=".cs" #> <# - void GeneratePackFromMethod(string pixelType, string converterCode) + void GenerateConvertToMethod(string pixelType) { #> /// - internal override void PackFrom<#=pixelType#>(ReadOnlySpan<<#=pixelType#>> source, Span destPixels, int count) + internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - - ref <#=pixelType#> sourceRef = ref MemoryMarshal.GetReference(source); - ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); - - for (int i = 0; i < count; i++) - { - ref <#=pixelType#> sp = ref Unsafe.Add(ref sourceRef, i); - ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); - <#=converterCode#> - } - } - <# - } - - void GenerateConvertToMethod(string pixelType, string converterCode) - { - #> - - /// - internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> dest, int count) - { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); ref Rgba32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); - ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(dest); + ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); for (int i = 0; i < count; i++) { ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i); ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); - <#=converterCode#> + + dp.PackFromRgba32(sp); } } <# @@ -68,20 +47,37 @@ namespace SixLabors.ImageSharp.PixelFormats /// public partial struct Rgba32 { + + /// + /// Provides optimized overrides for bulk operations. + /// internal partial class PixelOperations { - <# - GeneratePackFromMethod("Rgb24", "Unsafe.As(ref dp) = sp; dp.A = byte.MaxValue;"); - GenerateConvertToMethod("Rgb24", "dp = Unsafe.As(ref sp);"); + /// + internal override void PackFromRgba32(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); - GeneratePackFromMethod("Bgr24", "dp.Bgr = sp; dp.A = byte.MaxValue;"); - GenerateConvertToMethod("Bgr24", "dp = sp.Bgr;"); - - GeneratePackFromMethod("Bgra32", "dp.R = sp.R; dp.G = sp.G; dp.B = sp.B; dp.A = sp.A;"); - GenerateConvertToMethod("Bgra32", "dp.PackFromRgba32(sp);"); + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); - GeneratePackFromMethod("Argb32", "dp.R = sp.R; dp.G = sp.G; dp.B = sp.B; dp.A = sp.A;"); - GenerateConvertToMethod("Argb32", "dp.PackFromRgba32(sp);"); + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + <# + GenerateConvertToMethod("Argb32"); + GenerateConvertToMethod("Bgr24"); + GenerateConvertToMethod("Bgra32"); + GenerateConvertToMethod("Gray8"); + GenerateConvertToMethod("Gray16"); + GenerateConvertToMethod("Rgb24"); + GenerateConvertToMethod("Rgb48"); + GenerateConvertToMethod("Rgba64"); #> } diff --git a/src/ImageSharp/PixelFormats/Generated/Rgba64.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/Generated/Rgba64.PixelOperations.Generated.cs new file mode 100644 index 0000000000..e6f9b37a70 --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Rgba64.PixelOperations.Generated.cs @@ -0,0 +1,177 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Rgba64 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromRgba64(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + + /// + internal override void ToArgb32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Argb32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); + ref Argb32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba64(sp); + } + } + + /// + internal override void ToBgr24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgr24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgr24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba64(sp); + } + } + + /// + internal override void ToBgra32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Bgra32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); + ref Bgra32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba64(sp); + } + } + + /// + internal override void ToGray8(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray8 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray8 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba64(sp); + } + } + + /// + internal override void ToGray16(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Gray16 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray16 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba64(sp); + } + } + + /// + internal override void ToRgb24(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb24 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb24 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba64(sp); + } + } + + /// + internal override void ToRgba32(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgba32 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgba32 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba64(sp); + } + } + + /// + internal override void ToRgb48(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref Rgb48 destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); + ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba64(sp); + } + } + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Generated/Rgba64.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/Generated/Rgba64.PixelOperations.Generated.tt new file mode 100644 index 0000000000..e998341570 --- /dev/null +++ b/src/ImageSharp/PixelFormats/Generated/Rgba64.PixelOperations.Generated.tt @@ -0,0 +1,85 @@ +<# +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. +#> +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + void GenerateConvertToMethod(string pixelType) + { + #> + + /// + internal override void To<#=pixelType#>(ReadOnlySpan sourcePixels, Span<<#=pixelType#>> destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + ref Rgba64 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); + ref <#=pixelType#> destRef = ref MemoryMarshal.GetReference(destPixels); + + for (int i = 0; i < count; i++) + { + ref Rgba64 sp = ref Unsafe.Add(ref sourceRef, i); + ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i); + + dp.PackFromRgba64(sp); + } + } + <# + } +#> +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +// +namespace SixLabors.ImageSharp.PixelFormats +{ + using System; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + /// + /// Provides optimized overrides for bulk operations. + /// + public partial struct Rgba64 + { + + /// + /// Provides optimized overrides for bulk operations. + /// + internal class PixelOperations : PixelOperations + { + /// + internal override void PackFromRgba64(ReadOnlySpan source, Span destPixels, int count) + { + GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + + source.Slice(0, count).CopyTo(destPixels); + } + + /// + internal override void ToRgba64(ReadOnlySpan sourcePixels, Span destPixels, int count) + { + GuardSpans(sourcePixels, nameof(sourcePixels), destPixels, nameof(destPixels), count); + + sourcePixels.Slice(0, count).CopyTo(destPixels); + } + + <# + GenerateConvertToMethod("Argb32"); + GenerateConvertToMethod("Bgr24"); + GenerateConvertToMethod("Bgra32"); + GenerateConvertToMethod("Gray8"); + GenerateConvertToMethod("Gray16"); + GenerateConvertToMethod("Rgb24"); + GenerateConvertToMethod("Rgba32"); + GenerateConvertToMethod("Rgb48"); + #> + + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Gray16.cs b/src/ImageSharp/PixelFormats/Gray16.cs index f9aada9374..34f221d79c 100644 --- a/src/ImageSharp/PixelFormats/Gray16.cs +++ b/src/ImageSharp/PixelFormats/Gray16.cs @@ -13,9 +13,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// Ranges from [0, 0, 0, 1] to [1, 1, 1, 1] in vector form. /// /// - public struct Gray16 : IPixel, IPackedVector + public partial struct Gray16 : IPixel, IPackedVector { private const float Max = ushort.MaxValue; + private const float Average = 1 / 3F; /// /// Initializes a new instance of the struct. @@ -49,7 +50,7 @@ namespace SixLabors.ImageSharp.PixelFormats public static bool operator !=(Gray16 left, Gray16 right) => !left.Equals(right); /// - public PixelOperations CreatePixelOperations() => new PixelOperations(); + public PixelOperations CreatePixelOperations() => new PixelOperations(); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -63,11 +64,8 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromVector4(Vector4 vector) { - vector = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * Max; - this.PackedValue = ImageMaths.Get16BitBT709Luminance( - (ushort)MathF.Round(vector.X), - (ushort)MathF.Round(vector.Y), - (ushort)MathF.Round(vector.Z)); + vector = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * Max * Average; + this.PackedValue = (ushort)MathF.Round(vector.X + vector.Y + vector.Z); } /// @@ -88,6 +86,16 @@ namespace SixLabors.ImageSharp.PixelFormats ImageMaths.UpscaleFrom8BitTo16Bit(source.B)); } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) + { + this.PackedValue = ImageMaths.Get16BitBT709Luminance( + ImageMaths.UpscaleFrom8BitTo16Bit(source.R), + ImageMaths.UpscaleFrom8BitTo16Bit(source.G), + ImageMaths.UpscaleFrom8BitTo16Bit(source.B)); + } + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) @@ -106,6 +114,16 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackedValue = source.PackedValue; + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) + { + this.PackedValue = ImageMaths.Get16BitBT709Luminance( + ImageMaths.UpscaleFrom8BitTo16Bit(source.R), + ImageMaths.UpscaleFrom8BitTo16Bit(source.G), + ImageMaths.UpscaleFrom8BitTo16Bit(source.B)); + } + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) @@ -130,7 +148,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba64(Rgba64 source) => ImageMaths.Get16BitBT709Luminance(source.R, source.G, source.B); + public void PackFromRgba64(Rgba64 source) => this.PackedValue = ImageMaths.Get16BitBT709Luminance(source.R, source.G, source.B); /// public override bool Equals(object obj) => obj is Gray16 other && this.Equals(other); @@ -145,5 +163,15 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() => this.PackedValue.GetHashCode(); + + [MethodImpl(InliningOptions.ShortMethod)] + internal void ConvertFromRgbaScaledVector4(Vector4 vector) + { + vector = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * Max; + this.PackedValue = ImageMaths.Get16BitBT709Luminance( + (ushort)MathF.Round(vector.X), + (ushort)MathF.Round(vector.Y), + (ushort)MathF.Round(vector.Z)); + } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Gray8.cs b/src/ImageSharp/PixelFormats/Gray8.cs index b1fa2b1e14..5812405876 100644 --- a/src/ImageSharp/PixelFormats/Gray8.cs +++ b/src/ImageSharp/PixelFormats/Gray8.cs @@ -12,17 +12,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// Ranges from [0, 0, 0, 1] to [1, 1, 1, 1] in vector form. /// /// - public struct Gray8 : IPixel, IPackedVector + public partial struct Gray8 : IPixel, IPackedVector { - /// - /// The maximum byte value. - /// private static readonly Vector4 MaxBytes = new Vector4(255F); - - /// - /// The half vector value. - /// private static readonly Vector4 Half = new Vector4(0.5F); + private const float Average = 1 / 3F; /// /// Initializes a new instance of the struct. @@ -56,7 +50,7 @@ namespace SixLabors.ImageSharp.PixelFormats public static bool operator !=(Gray8 left, Gray8 right) => !left.Equals(right); /// - public PixelOperations CreatePixelOperations() => new PixelOperations(); + public PixelOperations CreatePixelOperations() => new PixelOperations(); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -72,9 +66,8 @@ namespace SixLabors.ImageSharp.PixelFormats { vector *= MaxBytes; vector += Half; - vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes); - - this.PackedValue = ImageMaths.Get8BitBT709Luminance((byte)vector.X, (byte)vector.Y, (byte)vector.Z); + vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes) * Average; + this.PackedValue = (byte)(vector.X + vector.Y + vector.Z); } /// @@ -89,6 +82,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackedValue = ImageMaths.Get8BitBT709Luminance(source.R, source.G, source.B); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackedValue = ImageMaths.Get8BitBT709Luminance(source.R, source.G, source.B); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackedValue = ImageMaths.Get8BitBT709Luminance(source.R, source.G, source.B); @@ -101,6 +98,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackedValue = ImageMaths.DownScaleFrom16BitTo8Bit(source.PackedValue); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackedValue = ImageMaths.Get8BitBT709Luminance(source.R, source.G, source.B); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackedValue = ImageMaths.Get8BitBT709Luminance(source.R, source.G, source.B); @@ -138,5 +139,14 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() => this.PackedValue.GetHashCode(); + + [MethodImpl(InliningOptions.ShortMethod)] + internal void ConvertFromRgbaScaledVector4(Vector4 vector) + { + vector *= MaxBytes; + vector += Half; + vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes); + this.PackedValue = ImageMaths.Get8BitBT709Luminance((byte)vector.X, (byte)vector.Y, (byte)vector.Z); + } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/HalfSingle.cs b/src/ImageSharp/PixelFormats/HalfSingle.cs index 8048a3825d..78edc9a08e 100644 --- a/src/ImageSharp/PixelFormats/HalfSingle.cs +++ b/src/ImageSharp/PixelFormats/HalfSingle.cs @@ -14,16 +14,6 @@ namespace SixLabors.ImageSharp.PixelFormats /// public struct HalfSingle : IPixel, IPackedVector { - /// - /// The maximum byte value. - /// - private static readonly Vector4 MaxBytes = new Vector4(255); - - /// - /// The half vector value. - /// - private static readonly Vector4 Half = new Vector4(0.5F); - /// /// Initializes a new instance of the struct. /// @@ -89,6 +79,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -101,6 +95,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -137,14 +135,5 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() => this.PackedValue.GetHashCode(); - - [MethodImpl(InliningOptions.ShortMethod)] - private Vector4 ToByteScaledVector4() - { - var vector = this.ToVector4(); - vector *= MaxBytes; - vector += Half; - return Vector4.Clamp(vector, Vector4.Zero, MaxBytes); - } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/HalfVector2.cs b/src/ImageSharp/PixelFormats/HalfVector2.cs index f398f508ba..e3777bc2fb 100644 --- a/src/ImageSharp/PixelFormats/HalfVector2.cs +++ b/src/ImageSharp/PixelFormats/HalfVector2.cs @@ -90,6 +90,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -102,6 +106,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/HalfVector4.cs b/src/ImageSharp/PixelFormats/HalfVector4.cs index 45d93efc09..079c3ee383 100644 --- a/src/ImageSharp/PixelFormats/HalfVector4.cs +++ b/src/ImageSharp/PixelFormats/HalfVector4.cs @@ -98,6 +98,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -110,6 +114,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/IPixel.cs b/src/ImageSharp/PixelFormats/IPixel.cs index a3017501ce..87125fa0a3 100644 --- a/src/ImageSharp/PixelFormats/IPixel.cs +++ b/src/ImageSharp/PixelFormats/IPixel.cs @@ -61,6 +61,12 @@ namespace SixLabors.ImageSharp.PixelFormats /// The value. void PackFromArgb32(Argb32 source); + /// + /// Packs the pixel from an value. + /// + /// The value. + void PackFromBgr24(Bgr24 source); + /// /// Packs the pixel from an value. /// @@ -79,6 +85,12 @@ namespace SixLabors.ImageSharp.PixelFormats /// The value. void PackFromGray16(Gray16 source); + /// + /// Packs the pixel from an value. + /// + /// The value. + void PackFromRgb24(Rgb24 source); + /// /// Packs the pixel from an value. /// diff --git a/src/ImageSharp/PixelFormats/NormalizedByte2.cs b/src/ImageSharp/PixelFormats/NormalizedByte2.cs index 86b5280902..3eaa69c03e 100644 --- a/src/ImageSharp/PixelFormats/NormalizedByte2.cs +++ b/src/ImageSharp/PixelFormats/NormalizedByte2.cs @@ -97,6 +97,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -113,6 +117,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/NormalizedByte4.cs b/src/ImageSharp/PixelFormats/NormalizedByte4.cs index b538e4a449..e0e3e65020 100644 --- a/src/ImageSharp/PixelFormats/NormalizedByte4.cs +++ b/src/ImageSharp/PixelFormats/NormalizedByte4.cs @@ -102,6 +102,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -114,6 +118,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/NormalizedShort2.cs b/src/ImageSharp/PixelFormats/NormalizedShort2.cs index 6135826f48..0aa5736379 100644 --- a/src/ImageSharp/PixelFormats/NormalizedShort2.cs +++ b/src/ImageSharp/PixelFormats/NormalizedShort2.cs @@ -97,6 +97,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -109,6 +113,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/NormalizedShort4.cs b/src/ImageSharp/PixelFormats/NormalizedShort4.cs index 9717829a24..577e901544 100644 --- a/src/ImageSharp/PixelFormats/NormalizedShort4.cs +++ b/src/ImageSharp/PixelFormats/NormalizedShort4.cs @@ -104,6 +104,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -116,6 +120,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index b12a2bfa58..f1b40e81f0 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -105,6 +105,60 @@ namespace SixLabors.ImageSharp.PixelFormats } } + /// + /// Performs a bulk conversion of a collection of one pixel format into another. + /// + /// The pixel format. + /// The to the source colors. + /// The to the destination colors. + /// The number of pixels to convert. + internal virtual void To(ReadOnlySpan sourceColors, Span destinationColors, int count) + where TPixel2 : struct, IPixel + { + GuardSpans(sourceColors, nameof(sourceColors), destinationColors, nameof(destinationColors), count); + + ref TPixel sourceRef = ref MemoryMarshal.GetReference(sourceColors); + + // Gray8 and Gray16 are special implementations of IPixel in that they do not conform to the + // standard RGBA colorspace format and must be converted from RGBA using the special ITU BT709 alogrithm. + // One of the requirements of PackFromScaledVector4/ToScaledVector4 is that it unaware of this and + // packs/unpacks the pixel without and conversion so we employ custom methods do do this. + if (typeof(TPixel2).Equals(typeof(Gray16))) + { + ref Gray16 gray16Ref = ref MemoryMarshal.GetReference(MemoryMarshal.Cast(destinationColors)); + for (int i = 0; i < count; i++) + { + ref TPixel sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray16 dp = ref Unsafe.Add(ref gray16Ref, i); + dp.ConvertFromRgbaScaledVector4(sp.ToScaledVector4()); + } + + return; + } + + if (typeof(TPixel2).Equals(typeof(Gray8))) + { + ref Gray8 gray8Ref = ref MemoryMarshal.GetReference(MemoryMarshal.Cast(destinationColors)); + for (int i = 0; i < count; i++) + { + ref TPixel sp = ref Unsafe.Add(ref sourceRef, i); + ref Gray8 dp = ref Unsafe.Add(ref gray8Ref, i); + dp.ConvertFromRgbaScaledVector4(sp.ToScaledVector4()); + } + + return; + } + + // Normal converson + ref TPixel2 destRef = ref MemoryMarshal.GetReference(destinationColors); + for (int i = 0; i < count; i++) + { + ref TPixel sp = ref Unsafe.Add(ref sourceRef, i); + ref TPixel2 dp = ref Unsafe.Add(ref destRef, i); + dp.PackFromScaledVector4(sp.ToScaledVector4()); + } + } + /// /// Verifies that the given 'source' and 'destination' spans are at least of 'minLength' size. /// Throwing an if the condition is not met. diff --git a/src/ImageSharp/PixelFormats/Rg32.cs b/src/ImageSharp/PixelFormats/Rg32.cs index 3375a9753b..02c294b4ff 100644 --- a/src/ImageSharp/PixelFormats/Rg32.cs +++ b/src/ImageSharp/PixelFormats/Rg32.cs @@ -85,6 +85,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -97,6 +101,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/Rgb24.cs b/src/ImageSharp/PixelFormats/Rgb24.cs index ae037b3764..a2b896605d 100644 --- a/src/ImageSharp/PixelFormats/Rgb24.cs +++ b/src/ImageSharp/PixelFormats/Rgb24.cs @@ -15,7 +15,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// [StructLayout(LayoutKind.Explicit)] - public struct Rgb24 : IPixel + public partial struct Rgb24 : IPixel { /// /// The red component. @@ -91,7 +91,7 @@ namespace SixLabors.ImageSharp.PixelFormats public static bool operator !=(Rgb24 left, Rgb24 right) => !left.Equals(right); /// - public PixelOperations CreatePixelOperations() => new PixelOperations(); + public PixelOperations CreatePixelOperations() => new PixelOperations(); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -118,6 +118,15 @@ namespace SixLabors.ImageSharp.PixelFormats this.B = source.B; } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) + { + this.R = source.R; + this.G = source.G; + this.B = source.B; + } + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) @@ -148,7 +157,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) => this = Unsafe.As(ref source); + public void PackFromRgb24(Rgb24 source) => this = source; + + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgba32(Rgba32 source) => this = source.Rgb; /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/Rgb48.cs b/src/ImageSharp/PixelFormats/Rgb48.cs index 2ee1be6fe4..7406fda429 100644 --- a/src/ImageSharp/PixelFormats/Rgb48.cs +++ b/src/ImageSharp/PixelFormats/Rgb48.cs @@ -15,7 +15,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// [StructLayout(LayoutKind.Sequential)] - public struct Rgb48 : IPixel + public partial struct Rgb48 : IPixel { private const float Max = ushort.MaxValue; @@ -71,7 +71,7 @@ namespace SixLabors.ImageSharp.PixelFormats public static bool operator !=(Rgb48 left, Rgb48 right) => !left.Equals(right); /// - public PixelOperations CreatePixelOperations() => new PixelOperations(); + public PixelOperations CreatePixelOperations() => new PixelOperations(); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -104,6 +104,15 @@ namespace SixLabors.ImageSharp.PixelFormats this.B = ImageMaths.UpscaleFrom8BitTo16Bit(source.B); } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) + { + this.R = ImageMaths.UpscaleFrom8BitTo16Bit(source.R); + this.G = ImageMaths.UpscaleFrom8BitTo16Bit(source.G); + this.B = ImageMaths.UpscaleFrom8BitTo16Bit(source.B); + } + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) @@ -136,6 +145,15 @@ namespace SixLabors.ImageSharp.PixelFormats this.B = source.PackedValue; } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) + { + this.R = ImageMaths.UpscaleFrom8BitTo16Bit(source.R); + this.G = ImageMaths.UpscaleFrom8BitTo16Bit(source.G); + this.B = ImageMaths.UpscaleFrom8BitTo16Bit(source.B); + } + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) diff --git a/src/ImageSharp/PixelFormats/Rgba1010102.cs b/src/ImageSharp/PixelFormats/Rgba1010102.cs index 8bcf34f309..86b639e229 100644 --- a/src/ImageSharp/PixelFormats/Rgba1010102.cs +++ b/src/ImageSharp/PixelFormats/Rgba1010102.cs @@ -91,6 +91,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -105,16 +109,20 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); - /// + /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba64(Rgba64 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs b/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs index 40d8e0190d..3111a6ee15 100644 --- a/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/Rgba32.PixelOperations.cs @@ -86,33 +86,10 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToVector4(ReadOnlySpan sourceColors, Span destinationVectors, int count) - { - Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors)); - Guard.MustBeSizedAtLeast(destinationVectors, count, nameof(destinationVectors)); - - if (count < 256 || !Vector.IsHardwareAccelerated) - { - // Doesn't worth to bother with SIMD: - base.ToVector4(sourceColors, destinationVectors, count); - return; - } - - int remainder = count % Vector.Count; - int alignedCount = count - remainder; - - if (alignedCount > 0) - { - ToVector4SimdAligned(sourceColors, destinationVectors, alignedCount); - } + internal override void PackFromScaledVector4(ReadOnlySpan sourceVectors, Span destinationColors, int count) => this.PackFromVector4(sourceVectors, destinationColors, count); - if (remainder > 0) - { - sourceColors = sourceColors.Slice(alignedCount); - destinationVectors = destinationVectors.Slice(alignedCount); - base.ToVector4(sourceColors, destinationVectors, remainder); - } - } + /// + internal override void ToScaledVector4(ReadOnlySpan sourceColors, Span destinationVectors, int count) => this.ToVector4(sourceColors, destinationVectors, count); /// internal override void PackFromVector4(ReadOnlySpan sourceVectors, Span destinationColors, int count) @@ -145,25 +122,32 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - internal override void ToScaledVector4(ReadOnlySpan sourceColors, Span destinationVectors, int count) => this.ToVector4(sourceColors, destinationVectors, count); - - /// - internal override void PackFromScaledVector4(ReadOnlySpan sourceVectors, Span destinationColors, int count) => this.PackFromVector4(sourceVectors, destinationColors, count); - - /// - internal override void PackFromRgba32(ReadOnlySpan source, Span destPixels, int count) + internal override void ToVector4(ReadOnlySpan sourceColors, Span destinationVectors, int count) { - GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count); + Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors)); + Guard.MustBeSizedAtLeast(destinationVectors, count, nameof(destinationVectors)); - source.Slice(0, count).CopyTo(destPixels); - } + if (count < 256 || !Vector.IsHardwareAccelerated) + { + // Doesn't worth to bother with SIMD: + base.ToVector4(sourceColors, destinationVectors, count); + return; + } - /// - internal override void ToRgba32(ReadOnlySpan sourcePixels, Span dest, int count) - { - GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count); + int remainder = count % Vector.Count; + int alignedCount = count - remainder; - sourcePixels.Slice(0, count).CopyTo(dest); + if (alignedCount > 0) + { + ToVector4SimdAligned(sourceColors, destinationVectors, alignedCount); + } + + if (remainder > 0) + { + sourceColors = sourceColors.Slice(alignedCount); + destinationVectors = destinationVectors.Slice(alignedCount); + base.ToVector4(sourceColors, destinationVectors, remainder); + } } /// diff --git a/src/ImageSharp/PixelFormats/Rgba32.cs b/src/ImageSharp/PixelFormats/Rgba32.cs index 83620c823c..e7814d23ac 100644 --- a/src/ImageSharp/PixelFormats/Rgba32.cs +++ b/src/ImageSharp/PixelFormats/Rgba32.cs @@ -246,6 +246,14 @@ namespace SixLabors.ImageSharp.PixelFormats this.A = source.A; } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) + { + this.Bgr = source; + this.A = byte.MaxValue; + } + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) @@ -277,6 +285,14 @@ namespace SixLabors.ImageSharp.PixelFormats this.A = byte.MaxValue; } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) + { + this.Rgb = source; + this.A = byte.MaxValue; + } + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this = source; diff --git a/src/ImageSharp/PixelFormats/Rgba64.cs b/src/ImageSharp/PixelFormats/Rgba64.cs index 623f7051af..738c5e3dd8 100644 --- a/src/ImageSharp/PixelFormats/Rgba64.cs +++ b/src/ImageSharp/PixelFormats/Rgba64.cs @@ -15,7 +15,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// [StructLayout(LayoutKind.Sequential)] - public struct Rgba64 : IPixel, IPackedVector + public partial struct Rgba64 : IPixel, IPackedVector { private const float Max = ushort.MaxValue; @@ -99,7 +99,7 @@ namespace SixLabors.ImageSharp.PixelFormats public static bool operator !=(Rgba64 left, Rgba64 right) => left.PackedValue != right.PackedValue; /// - public PixelOperations CreatePixelOperations() => new PixelOperations(); + public PixelOperations CreatePixelOperations() => new PixelOperations(); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -134,6 +134,16 @@ namespace SixLabors.ImageSharp.PixelFormats this.A = ImageMaths.UpscaleFrom8BitTo16Bit(source.A); } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) + { + this.R = ImageMaths.UpscaleFrom8BitTo16Bit(source.R); + this.G = ImageMaths.UpscaleFrom8BitTo16Bit(source.G); + this.B = ImageMaths.UpscaleFrom8BitTo16Bit(source.B); + this.A = ushort.MaxValue; + } + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) @@ -165,6 +175,16 @@ namespace SixLabors.ImageSharp.PixelFormats this.A = ushort.MaxValue; } + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) + { + this.R = ImageMaths.UpscaleFrom8BitTo16Bit(source.R); + this.G = ImageMaths.UpscaleFrom8BitTo16Bit(source.G); + this.B = ImageMaths.UpscaleFrom8BitTo16Bit(source.B); + this.A = ushort.MaxValue; + } + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) diff --git a/src/ImageSharp/PixelFormats/RgbaVector.Definitions.cs b/src/ImageSharp/PixelFormats/RgbaVector.Definitions.cs deleted file mode 100644 index 2ef37c43ae..0000000000 --- a/src/ImageSharp/PixelFormats/RgbaVector.Definitions.cs +++ /dev/null @@ -1,721 +0,0 @@ -// Copyright (c) Six Labors and contributors. -// Licensed under the Apache License, Version 2.0. - -namespace SixLabors.ImageSharp.PixelFormats -{ - /// - /// Provides operators and composition algorithms. - /// - public partial struct RgbaVector - { - /// - /// Represents a matching the W3C definition that has an hex value of #F0F8FF. - /// - public static readonly RgbaVector AliceBlue = NamedColors.AliceBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #FAEBD7. - /// - public static readonly RgbaVector AntiqueWhite = NamedColors.AntiqueWhite; - - /// - /// Represents a matching the W3C definition that has an hex value of #00FFFF. - /// - public static readonly RgbaVector Aqua = NamedColors.Aqua; - - /// - /// Represents a matching the W3C definition that has an hex value of #7FFFD4. - /// - public static readonly RgbaVector Aquamarine = NamedColors.Aquamarine; - - /// - /// Represents a matching the W3C definition that has an hex value of #F0FFFF. - /// - public static readonly RgbaVector Azure = NamedColors.Azure; - - /// - /// Represents a matching the W3C definition that has an hex value of #F5F5DC. - /// - public static readonly RgbaVector Beige = NamedColors.Beige; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFE4C4. - /// - public static readonly RgbaVector Bisque = NamedColors.Bisque; - - /// - /// Represents a matching the W3C definition that has an hex value of #000000. - /// - public static readonly RgbaVector Black = NamedColors.Black; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFEBCD. - /// - public static readonly RgbaVector BlanchedAlmond = NamedColors.BlanchedAlmond; - - /// - /// Represents a matching the W3C definition that has an hex value of #0000FF. - /// - public static readonly RgbaVector Blue = NamedColors.Blue; - - /// - /// Represents a matching the W3C definition that has an hex value of #8A2BE2. - /// - public static readonly RgbaVector BlueViolet = NamedColors.BlueViolet; - - /// - /// Represents a matching the W3C definition that has an hex value of #A52A2A. - /// - public static readonly RgbaVector Brown = NamedColors.Brown; - - /// - /// Represents a matching the W3C definition that has an hex value of #DEB887. - /// - public static readonly RgbaVector BurlyWood = NamedColors.BurlyWood; - - /// - /// Represents a matching the W3C definition that has an hex value of #5F9EA0. - /// - public static readonly RgbaVector CadetBlue = NamedColors.CadetBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #7FFF00. - /// - public static readonly RgbaVector Chartreuse = NamedColors.Chartreuse; - - /// - /// Represents a matching the W3C definition that has an hex value of #D2691E. - /// - public static readonly RgbaVector Chocolate = NamedColors.Chocolate; - - /// - /// Represents a matching the W3C definition that has an hex value of #FF7F50. - /// - public static readonly RgbaVector Coral = NamedColors.Coral; - - /// - /// Represents a matching the W3C definition that has an hex value of #6495ED. - /// - public static readonly RgbaVector CornflowerBlue = NamedColors.CornflowerBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFF8DC. - /// - public static readonly RgbaVector Cornsilk = NamedColors.Cornsilk; - - /// - /// Represents a matching the W3C definition that has an hex value of #DC143C. - /// - public static readonly RgbaVector Crimson = NamedColors.Crimson; - - /// - /// Represents a matching the W3C definition that has an hex value of #00FFFF. - /// - public static readonly RgbaVector Cyan = NamedColors.Cyan; - - /// - /// Represents a matching the W3C definition that has an hex value of #00008B. - /// - public static readonly RgbaVector DarkBlue = NamedColors.DarkBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #008B8B. - /// - public static readonly RgbaVector DarkCyan = NamedColors.DarkCyan; - - /// - /// Represents a matching the W3C definition that has an hex value of #B8860B. - /// - public static readonly RgbaVector DarkGoldenrod = NamedColors.DarkGoldenrod; - - /// - /// Represents a matching the W3C definition that has an hex value of #A9A9A9. - /// - public static readonly RgbaVector DarkGray = NamedColors.DarkGray; - - /// - /// Represents a matching the W3C definition that has an hex value of #006400. - /// - public static readonly RgbaVector DarkGreen = NamedColors.DarkGreen; - - /// - /// Represents a matching the W3C definition that has an hex value of #BDB76B. - /// - public static readonly RgbaVector DarkKhaki = NamedColors.DarkKhaki; - - /// - /// Represents a matching the W3C definition that has an hex value of #8B008B. - /// - public static readonly RgbaVector DarkMagenta = NamedColors.DarkMagenta; - - /// - /// Represents a matching the W3C definition that has an hex value of #556B2F. - /// - public static readonly RgbaVector DarkOliveGreen = NamedColors.DarkOliveGreen; - - /// - /// Represents a matching the W3C definition that has an hex value of #FF8C00. - /// - public static readonly RgbaVector DarkOrange = NamedColors.DarkOrange; - - /// - /// Represents a matching the W3C definition that has an hex value of #9932CC. - /// - public static readonly RgbaVector DarkOrchid = NamedColors.DarkOrchid; - - /// - /// Represents a matching the W3C definition that has an hex value of #8B0000. - /// - public static readonly RgbaVector DarkRed = NamedColors.DarkRed; - - /// - /// Represents a matching the W3C definition that has an hex value of #E9967A. - /// - public static readonly RgbaVector DarkSalmon = NamedColors.DarkSalmon; - - /// - /// Represents a matching the W3C definition that has an hex value of #8FBC8B. - /// - public static readonly RgbaVector DarkSeaGreen = NamedColors.DarkSeaGreen; - - /// - /// Represents a matching the W3C definition that has an hex value of #483D8B. - /// - public static readonly RgbaVector DarkSlateBlue = NamedColors.DarkSlateBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #2F4F4F. - /// - public static readonly RgbaVector DarkSlateGray = NamedColors.DarkSlateGray; - - /// - /// Represents a matching the W3C definition that has an hex value of #00CED1. - /// - public static readonly RgbaVector DarkTurquoise = NamedColors.DarkTurquoise; - - /// - /// Represents a matching the W3C definition that has an hex value of #9400D3. - /// - public static readonly RgbaVector DarkViolet = NamedColors.DarkViolet; - - /// - /// Represents a matching the W3C definition that has an hex value of #FF1493. - /// - public static readonly RgbaVector DeepPink = NamedColors.DeepPink; - - /// - /// Represents a matching the W3C definition that has an hex value of #00BFFF. - /// - public static readonly RgbaVector DeepSkyBlue = NamedColors.DeepSkyBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #696969. - /// - public static readonly RgbaVector DimGray = NamedColors.DimGray; - - /// - /// Represents a matching the W3C definition that has an hex value of #1E90FF. - /// - public static readonly RgbaVector DodgerBlue = NamedColors.DodgerBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #B22222. - /// - public static readonly RgbaVector Firebrick = NamedColors.Firebrick; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFFAF0. - /// - public static readonly RgbaVector FloralWhite = NamedColors.FloralWhite; - - /// - /// Represents a matching the W3C definition that has an hex value of #228B22. - /// - public static readonly RgbaVector ForestGreen = NamedColors.ForestGreen; - - /// - /// Represents a matching the W3C definition that has an hex value of #FF00FF. - /// - public static readonly RgbaVector Fuchsia = NamedColors.Fuchsia; - - /// - /// Represents a matching the W3C definition that has an hex value of #DCDCDC. - /// - public static readonly RgbaVector Gainsboro = NamedColors.Gainsboro; - - /// - /// Represents a matching the W3C definition that has an hex value of #F8F8FF. - /// - public static readonly RgbaVector GhostWhite = NamedColors.GhostWhite; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFD700. - /// - public static readonly RgbaVector Gold = NamedColors.Gold; - - /// - /// Represents a matching the W3C definition that has an hex value of #DAA520. - /// - public static readonly RgbaVector Goldenrod = NamedColors.Goldenrod; - - /// - /// Represents a matching the W3C definition that has an hex value of #808080. - /// - public static readonly RgbaVector Gray = NamedColors.Gray; - - /// - /// Represents a matching the W3C definition that has an hex value of #008000. - /// - public static readonly RgbaVector Green = NamedColors.Green; - - /// - /// Represents a matching the W3C definition that has an hex value of #ADFF2F. - /// - public static readonly RgbaVector GreenYellow = NamedColors.GreenYellow; - - /// - /// Represents a matching the W3C definition that has an hex value of #F0FFF0. - /// - public static readonly RgbaVector Honeydew = NamedColors.Honeydew; - - /// - /// Represents a matching the W3C definition that has an hex value of #FF69B4. - /// - public static readonly RgbaVector HotPink = NamedColors.HotPink; - - /// - /// Represents a matching the W3C definition that has an hex value of #CD5C5C. - /// - public static readonly RgbaVector IndianRed = NamedColors.IndianRed; - - /// - /// Represents a matching the W3C definition that has an hex value of #4B0082. - /// - public static readonly RgbaVector Indigo = NamedColors.Indigo; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFFFF0. - /// - public static readonly RgbaVector Ivory = NamedColors.Ivory; - - /// - /// Represents a matching the W3C definition that has an hex value of #F0E68C. - /// - public static readonly RgbaVector Khaki = NamedColors.Khaki; - - /// - /// Represents a matching the W3C definition that has an hex value of #E6E6FA. - /// - public static readonly RgbaVector Lavender = NamedColors.Lavender; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFF0F5. - /// - public static readonly RgbaVector LavenderBlush = NamedColors.LavenderBlush; - - /// - /// Represents a matching the W3C definition that has an hex value of #7CFC00. - /// - public static readonly RgbaVector LawnGreen = NamedColors.LawnGreen; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFFACD. - /// - public static readonly RgbaVector LemonChiffon = NamedColors.LemonChiffon; - - /// - /// Represents a matching the W3C definition that has an hex value of #ADD8E6. - /// - public static readonly RgbaVector LightBlue = NamedColors.LightBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #F08080. - /// - public static readonly RgbaVector LightCoral = NamedColors.LightCoral; - - /// - /// Represents a matching the W3C definition that has an hex value of #E0FFFF. - /// - public static readonly RgbaVector LightCyan = NamedColors.LightCyan; - - /// - /// Represents a matching the W3C definition that has an hex value of #FAFAD2. - /// - public static readonly RgbaVector LightGoldenrodYellow = NamedColors.LightGoldenrodYellow; - - /// - /// Represents a matching the W3C definition that has an hex value of #D3D3D3. - /// - public static readonly RgbaVector LightGray = NamedColors.LightGray; - - /// - /// Represents a matching the W3C definition that has an hex value of #90EE90. - /// - public static readonly RgbaVector LightGreen = NamedColors.LightGreen; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFB6C1. - /// - public static readonly RgbaVector LightPink = NamedColors.LightPink; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFA07A. - /// - public static readonly RgbaVector LightSalmon = NamedColors.LightSalmon; - - /// - /// Represents a matching the W3C definition that has an hex value of #20B2AA. - /// - public static readonly RgbaVector LightSeaGreen = NamedColors.LightSeaGreen; - - /// - /// Represents a matching the W3C definition that has an hex value of #87CEFA. - /// - public static readonly RgbaVector LightSkyBlue = NamedColors.LightSkyBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #778899. - /// - public static readonly RgbaVector LightSlateGray = NamedColors.LightSlateGray; - - /// - /// Represents a matching the W3C definition that has an hex value of #B0C4DE. - /// - public static readonly RgbaVector LightSteelBlue = NamedColors.LightSteelBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFFFE0. - /// - public static readonly RgbaVector LightYellow = NamedColors.LightYellow; - - /// - /// Represents a matching the W3C definition that has an hex value of #00FF00. - /// - public static readonly RgbaVector Lime = NamedColors.Lime; - - /// - /// Represents a matching the W3C definition that has an hex value of #32CD32. - /// - public static readonly RgbaVector LimeGreen = NamedColors.LimeGreen; - - /// - /// Represents a matching the W3C definition that has an hex value of #FAF0E6. - /// - public static readonly RgbaVector Linen = NamedColors.Linen; - - /// - /// Represents a matching the W3C definition that has an hex value of #FF00FF. - /// - public static readonly RgbaVector Magenta = NamedColors.Magenta; - - /// - /// Represents a matching the W3C definition that has an hex value of #800000. - /// - public static readonly RgbaVector Maroon = NamedColors.Maroon; - - /// - /// Represents a matching the W3C definition that has an hex value of #66CDAA. - /// - public static readonly RgbaVector MediumAquamarine = NamedColors.MediumAquamarine; - - /// - /// Represents a matching the W3C definition that has an hex value of #0000CD. - /// - public static readonly RgbaVector MediumBlue = NamedColors.MediumBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #BA55D3. - /// - public static readonly RgbaVector MediumOrchid = NamedColors.MediumOrchid; - - /// - /// Represents a matching the W3C definition that has an hex value of #9370DB. - /// - public static readonly RgbaVector MediumPurple = NamedColors.MediumPurple; - - /// - /// Represents a matching the W3C definition that has an hex value of #3CB371. - /// - public static readonly RgbaVector MediumSeaGreen = NamedColors.MediumSeaGreen; - - /// - /// Represents a matching the W3C definition that has an hex value of #7B68EE. - /// - public static readonly RgbaVector MediumSlateBlue = NamedColors.MediumSlateBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #00FA9A. - /// - public static readonly RgbaVector MediumSpringGreen = NamedColors.MediumSpringGreen; - - /// - /// Represents a matching the W3C definition that has an hex value of #48D1CC. - /// - public static readonly RgbaVector MediumTurquoise = NamedColors.MediumTurquoise; - - /// - /// Represents a matching the W3C definition that has an hex value of #C71585. - /// - public static readonly RgbaVector MediumVioletRed = NamedColors.MediumVioletRed; - - /// - /// Represents a matching the W3C definition that has an hex value of #191970. - /// - public static readonly RgbaVector MidnightBlue = NamedColors.MidnightBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #F5FFFA. - /// - public static readonly RgbaVector MintCream = NamedColors.MintCream; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFE4E1. - /// - public static readonly RgbaVector MistyRose = NamedColors.MistyRose; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFE4B5. - /// - public static readonly RgbaVector Moccasin = NamedColors.Moccasin; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFDEAD. - /// - public static readonly RgbaVector NavajoWhite = NamedColors.NavajoWhite; - - /// - /// Represents a matching the W3C definition that has an hex value of #000080. - /// - public static readonly RgbaVector Navy = NamedColors.Navy; - - /// - /// Represents a matching the W3C definition that has an hex value of #FDF5E6. - /// - public static readonly RgbaVector OldLace = NamedColors.OldLace; - - /// - /// Represents a matching the W3C definition that has an hex value of #808000. - /// - public static readonly RgbaVector Olive = NamedColors.Olive; - - /// - /// Represents a matching the W3C definition that has an hex value of #6B8E23. - /// - public static readonly RgbaVector OliveDrab = NamedColors.OliveDrab; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFA500. - /// - public static readonly RgbaVector Orange = NamedColors.Orange; - - /// - /// Represents a matching the W3C definition that has an hex value of #FF4500. - /// - public static readonly RgbaVector OrangeRed = NamedColors.OrangeRed; - - /// - /// Represents a matching the W3C definition that has an hex value of #DA70D6. - /// - public static readonly RgbaVector Orchid = NamedColors.Orchid; - - /// - /// Represents a matching the W3C definition that has an hex value of #EEE8AA. - /// - public static readonly RgbaVector PaleGoldenrod = NamedColors.PaleGoldenrod; - - /// - /// Represents a matching the W3C definition that has an hex value of #98FB98. - /// - public static readonly RgbaVector PaleGreen = NamedColors.PaleGreen; - - /// - /// Represents a matching the W3C definition that has an hex value of #AFEEEE. - /// - public static readonly RgbaVector PaleTurquoise = NamedColors.PaleTurquoise; - - /// - /// Represents a matching the W3C definition that has an hex value of #DB7093. - /// - public static readonly RgbaVector PaleVioletRed = NamedColors.PaleVioletRed; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFEFD5. - /// - public static readonly RgbaVector PapayaWhip = NamedColors.PapayaWhip; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFDAB9. - /// - public static readonly RgbaVector PeachPuff = NamedColors.PeachPuff; - - /// - /// Represents a matching the W3C definition that has an hex value of #CD853F. - /// - public static readonly RgbaVector Peru = NamedColors.Peru; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFC0CB. - /// - public static readonly RgbaVector Pink = NamedColors.Pink; - - /// - /// Represents a matching the W3C definition that has an hex value of #DDA0DD. - /// - public static readonly RgbaVector Plum = NamedColors.Plum; - - /// - /// Represents a matching the W3C definition that has an hex value of #B0E0E6. - /// - public static readonly RgbaVector PowderBlue = NamedColors.PowderBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #800080. - /// - public static readonly RgbaVector Purple = NamedColors.Purple; - - /// - /// Represents a matching the W3C definition that has an hex value of #663399. - /// - public static readonly RgbaVector RebeccaPurple = NamedColors.RebeccaPurple; - - /// - /// Represents a matching the W3C definition that has an hex value of #FF0000. - /// - public static readonly RgbaVector Red = NamedColors.Red; - - /// - /// Represents a matching the W3C definition that has an hex value of #BC8F8F. - /// - public static readonly RgbaVector RosyBrown = NamedColors.RosyBrown; - - /// - /// Represents a matching the W3C definition that has an hex value of #4169E1. - /// - public static readonly RgbaVector RoyalBlue = NamedColors.RoyalBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #8B4513. - /// - public static readonly RgbaVector SaddleBrown = NamedColors.SaddleBrown; - - /// - /// Represents a matching the W3C definition that has an hex value of #FA8072. - /// - public static readonly RgbaVector Salmon = NamedColors.Salmon; - - /// - /// Represents a matching the W3C definition that has an hex value of #F4A460. - /// - public static readonly RgbaVector SandyBrown = NamedColors.SandyBrown; - - /// - /// Represents a matching the W3C definition that has an hex value of #2E8B57. - /// - public static readonly RgbaVector SeaGreen = NamedColors.SeaGreen; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFF5EE. - /// - public static readonly RgbaVector SeaShell = NamedColors.SeaShell; - - /// - /// Represents a matching the W3C definition that has an hex value of #A0522D. - /// - public static readonly RgbaVector Sienna = NamedColors.Sienna; - - /// - /// Represents a matching the W3C definition that has an hex value of #C0C0C0. - /// - public static readonly RgbaVector Silver = NamedColors.Silver; - - /// - /// Represents a matching the W3C definition that has an hex value of #87CEEB. - /// - public static readonly RgbaVector SkyBlue = NamedColors.SkyBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #6A5ACD. - /// - public static readonly RgbaVector SlateBlue = NamedColors.SlateBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #708090. - /// - public static readonly RgbaVector SlateGray = NamedColors.SlateGray; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFFAFA. - /// - public static readonly RgbaVector Snow = NamedColors.Snow; - - /// - /// Represents a matching the W3C definition that has an hex value of #00FF7F. - /// - public static readonly RgbaVector SpringGreen = NamedColors.SpringGreen; - - /// - /// Represents a matching the W3C definition that has an hex value of #4682B4. - /// - public static readonly RgbaVector SteelBlue = NamedColors.SteelBlue; - - /// - /// Represents a matching the W3C definition that has an hex value of #D2B48C. - /// - public static readonly RgbaVector Tan = NamedColors.Tan; - - /// - /// Represents a matching the W3C definition that has an hex value of #008080. - /// - public static readonly RgbaVector Teal = NamedColors.Teal; - - /// - /// Represents a matching the W3C definition that has an hex value of #D8BFD8. - /// - public static readonly RgbaVector Thistle = NamedColors.Thistle; - - /// - /// Represents a matching the W3C definition that has an hex value of #FF6347. - /// - public static readonly RgbaVector Tomato = NamedColors.Tomato; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFFFFF. - /// - public static readonly RgbaVector Transparent = NamedColors.Transparent; - - /// - /// Represents a matching the W3C definition that has an hex value of #40E0D0. - /// - public static readonly RgbaVector Turquoise = NamedColors.Turquoise; - - /// - /// Represents a matching the W3C definition that has an hex value of #EE82EE. - /// - public static readonly RgbaVector Violet = NamedColors.Violet; - - /// - /// Represents a matching the W3C definition that has an hex value of #F5DEB3. - /// - public static readonly RgbaVector Wheat = NamedColors.Wheat; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFFFFF. - /// - public static readonly RgbaVector White = NamedColors.White; - - /// - /// Represents a matching the W3C definition that has an hex value of #F5F5F5. - /// - public static readonly RgbaVector WhiteSmoke = NamedColors.WhiteSmoke; - - /// - /// Represents a matching the W3C definition that has an hex value of #FFFF00. - /// - public static readonly RgbaVector Yellow = NamedColors.Yellow; - - /// - /// Represents a matching the W3C definition that has an hex value of #9ACD32. - /// - public static readonly RgbaVector YellowGreen = NamedColors.YellowGreen; - } -} \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/RgbaVector.PixelOperations.cs b/src/ImageSharp/PixelFormats/RgbaVector.PixelOperations.cs index ce40665cd4..aae6ee6940 100644 --- a/src/ImageSharp/PixelFormats/RgbaVector.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/RgbaVector.PixelOperations.cs @@ -18,11 +18,23 @@ namespace SixLabors.ImageSharp.PixelFormats internal class PixelOperations : PixelOperations { /// - internal override unsafe void ToVector4(ReadOnlySpan sourceColors, Span destVectors, int count) + internal override void PackFromScaledVector4(ReadOnlySpan sourceVectors, Span destinationColors, int count) { - GuardSpans(sourceColors, nameof(sourceColors), destVectors, nameof(destVectors), count); + GuardSpans(sourceVectors, nameof(sourceVectors), destinationColors, nameof(destinationColors), count); - MemoryMarshal.Cast(sourceColors).Slice(0, count).CopyTo(destVectors); + MemoryMarshal.Cast(sourceVectors).Slice(0, count).CopyTo(destinationColors); + } + + /// + internal override void ToScaledVector4(ReadOnlySpan sourceColors, Span destinationVectors, int count) + => this.ToVector4(sourceColors, destinationVectors, count); + + /// + internal override void ToVector4(ReadOnlySpan sourceColors, Span destinationVectors, int count) + { + GuardSpans(sourceColors, nameof(sourceColors), destinationVectors, nameof(destinationVectors), count); + + MemoryMarshal.Cast(sourceColors).Slice(0, count).CopyTo(destinationVectors); } } } diff --git a/src/ImageSharp/PixelFormats/RgbaVector.cs b/src/ImageSharp/PixelFormats/RgbaVector.cs index 5ca0ce406f..b5ccf8aedc 100644 --- a/src/ImageSharp/PixelFormats/RgbaVector.cs +++ b/src/ImageSharp/PixelFormats/RgbaVector.cs @@ -96,7 +96,7 @@ namespace SixLabors.ImageSharp.PixelFormats public static RgbaVector FromHex(string hex) => ColorBuilder.FromHex(hex); /// - public PixelOperations CreatePixelOperations() => new PixelOperations(); + public PixelOperations CreatePixelOperations() => new PixelOperations(); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -125,6 +125,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromArgb32(Argb32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); @@ -137,6 +141,10 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/Short2.cs b/src/ImageSharp/PixelFormats/Short2.cs index 24430a5d9f..db29b401ed 100644 --- a/src/ImageSharp/PixelFormats/Short2.cs +++ b/src/ImageSharp/PixelFormats/Short2.cs @@ -105,11 +105,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); + public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -119,10 +119,18 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/src/ImageSharp/PixelFormats/Short4.cs b/src/ImageSharp/PixelFormats/Short4.cs index 4925137470..6d6e5f0845 100644 --- a/src/ImageSharp/PixelFormats/Short4.cs +++ b/src/ImageSharp/PixelFormats/Short4.cs @@ -110,11 +110,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + public void PackFromBgr24(Bgr24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] - public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); + public void PackFromBgra32(Bgra32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -124,10 +124,18 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public void PackFromGray16(Gray16 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public void PackFromRgb24(Rgb24 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgba32(Rgba32 source) => this.PackFromScaledVector4(source.ToScaledVector4()); + /// + [MethodImpl(InliningOptions.ShortMethod)] + public Rgba32 ToRgba32() => new Rgba32(this.ToScaledVector4()); + /// [MethodImpl(InliningOptions.ShortMethod)] public void PackFromRgb48(Rgb48 source) => this.PackFromScaledVector4(source.ToScaledVector4()); diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs index 92b04f587e..e9cc98884a 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs @@ -13,20 +13,257 @@ using Xunit.Abstractions; namespace SixLabors.ImageSharp.Tests.PixelFormats { - public partial class PixelOperationsTests + public class PixelOperationsTests { - public class Rgba32 : PixelOperationsTests + public class Argb32OperationsTests : PixelOperationsTests { - public Rgba32(ITestOutputHelper output) + public Argb32OperationsTests(ITestOutputHelper output) : base(output) { } - // For 4.6 test runner MemberData does not work without redeclaring the public field in the derived test class: + // For 4.6 test runner MemberData does not work without redeclaring the public field in the + // derived test class: + // TODO: Can this not be delared in the parent class? public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; [Fact] - public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + } + + public class Bgr24OperationsTests : PixelOperationsTests + { + public Bgr24OperationsTests(ITestOutputHelper output) + : base(output) + { + } + + public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; + + [Fact] + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + } + + public class Bgra32OperationsTests : PixelOperationsTests + { + public Bgra32OperationsTests(ITestOutputHelper output) + : base(output) + { + } + + public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; + + [Fact] + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + } + + public class Gray8OperationsTests : PixelOperationsTests + { + public Gray8OperationsTests(ITestOutputHelper output) + : base(output) + { + } + + public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; + + [Fact] + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromGray8Bytes(int count) + { + byte[] source = CreateByteTestData(count); + var expected = new Gray8[count]; + + for (int i = 0; i < count; i++) + { + expected[i].PackFromGray8(new Gray8(source[i])); + } + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromGray8Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToGray8Bytes(int count) + { + Gray8[] source = CreatePixelTestData(count); + byte[] expected = new byte[count]; + var gray = default(Gray8); + + for (int i = 0; i < count; i++) + { + gray.PackFromScaledVector4(source[i].ToScaledVector4()); + expected[i] = gray.PackedValue; + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToGray8Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromGray16Bytes(int count) + { + byte[] source = CreateByteTestData(count * 2); + Span sourceSpan = source.AsSpan(); + var expected = new Gray8[count]; + + for (int i = 0; i < count; i++) + { + int i2 = i * 2; + expected[i].PackFromGray16(MemoryMarshal.Cast(sourceSpan.Slice(i2, 2))[0]); + } + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromGray16Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToGray16Bytes(int count) + { + Gray8[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 2]; + Gray16 gray = default; + + for (int i = 0; i < count; i++) + { + int i2 = i * 2; + gray.PackFromScaledVector4(source[i].ToScaledVector4()); + OctetBytes bytes = Unsafe.As(ref gray); + expected[i2] = bytes[0]; + expected[i2 + 1] = bytes[1]; + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToGray16Bytes(s, d.GetSpan(), count) + ); + } + } + + public class Gray16OperationsTests : PixelOperationsTests + { + public Gray16OperationsTests(ITestOutputHelper output) + : base(output) + { + } + + public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; + + [Fact] + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromGray8Bytes(int count) + { + byte[] source = CreateByteTestData(count); + var expected = new Gray16[count]; + + for (int i = 0; i < count; i++) + { + expected[i].PackFromGray8(new Gray8(source[i])); + } + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromGray8Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToGray8Bytes(int count) + { + Gray16[] source = CreatePixelTestData(count); + byte[] expected = new byte[count]; + var gray = default(Gray8); + + for (int i = 0; i < count; i++) + { + gray.PackFromScaledVector4(source[i].ToScaledVector4()); + expected[i] = gray.PackedValue; + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToGray8Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void PackFromGray16Bytes(int count) + { + byte[] source = CreateByteTestData(count * 2); + Span sourceSpan = source.AsSpan(); + var expected = new Gray16[count]; + + for (int i = 0; i < count; i++) + { + int i2 = i * 2; + expected[i].PackFromGray16(MemoryMarshal.Cast(sourceSpan.Slice(i2, 2))[0]); + } + + TestOperation( + source, + expected, + (s, d) => Operations.PackFromGray16Bytes(s, d.GetSpan(), count) + ); + } + + [Theory] + [MemberData(nameof(ArraySizesData))] + public void ToGray16Bytes(int count) + { + Gray16[] source = CreatePixelTestData(count); + byte[] expected = new byte[count * 2]; + Gray16 gray = default; + + for (int i = 0; i < count; i++) + { + int i2 = i * 2; + gray.PackFromScaledVector4(source[i].ToScaledVector4()); + OctetBytes bytes = Unsafe.As(ref gray); + expected[i2] = bytes[0]; + expected[i2 + 1] = bytes[1]; + } + + TestOperation( + source, + expected, + (s, d) => Operations.ToGray16Bytes(s, d.GetSpan(), count) + ); + } + } + + public class Rgba32OperationsTests : PixelOperationsTests + { + public Rgba32OperationsTests(ITestOutputHelper output) + : base(output) + { + } + + public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; + + [Fact] + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); [Fact] public void ToVector4SimdAligned() @@ -36,63 +273,86 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats return; } - ImageSharp.PixelFormats.Rgba32[] source = CreatePixelTestData(64); + Rgba32[] source = CreatePixelTestData(64); Vector4[] expected = CreateExpectedVector4Data(source); TestOperation( source, expected, - (s, d) => ImageSharp.PixelFormats.Rgba32.PixelOperations.ToVector4SimdAligned(s, d.GetSpan(), 64) + (s, d) => Rgba32.PixelOperations.ToVector4SimdAligned(s, d.GetSpan(), 64) ); } - // [Fact] // Profiling benchmark - enable manually! #pragma warning disable xUnit1013 // Public method should be marked as test public void Benchmark_ToVector4() #pragma warning restore xUnit1013 // Public method should be marked as test { - int times = 200000; - int count = 1024; + const int times = 200000; + const int count = 1024; - using (IMemoryOwner source = Configuration.Default.MemoryAllocator.Allocate(count)) + using (IMemoryOwner source = Configuration.Default.MemoryAllocator.Allocate(count)) using (IMemoryOwner dest = Configuration.Default.MemoryAllocator.Allocate(count)) { this.Measure( times, - () => - { - PixelOperations.Instance.ToVector4(source.GetSpan(), dest.GetSpan(), count); - }); + () => PixelOperations.Instance.ToVector4(source.GetSpan(), dest.GetSpan(), count)); } } } - public class Argb32 : PixelOperationsTests + public class Rgb48OperationsTests : PixelOperationsTests { - // For 4.6 test runner MemberData does not work without redeclaring the public field in the derived test class: - public Argb32(ITestOutputHelper output) + public Rgb48OperationsTests(ITestOutputHelper output) : base(output) { } public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; + + [Fact] + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + } + + public class Rgba64OperationsTests : PixelOperationsTests + { + public Rgba64OperationsTests(ITestOutputHelper output) + : base(output) + { + } + + public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; + + [Fact] + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); + } + + public class RgbaVectorOperationsTests : PixelOperationsTests + { + public RgbaVectorOperationsTests(ITestOutputHelper output) + : base(output) + { + } + + public static new TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; + + [Fact] + public void IsSpecialImplementation() => Assert.IsType(PixelOperations.Instance); } [Theory] [WithBlankImages(1, 1, PixelTypes.All)] - public void GetGlobalInstance(TestImageProvider dummy) + public void GetGlobalInstance(TestImageProvider _) where TPixel : struct, IPixel => Assert.NotNull(PixelOperations.Instance); [Fact] public void IsOpaqueColor() { - Assert.True(new GraphicsOptions(true).IsOpaqueColorWithoutBlending(ImageSharp.PixelFormats.Rgba32.Red)); - - Assert.False(new GraphicsOptions(true, 0.5f).IsOpaqueColorWithoutBlending(ImageSharp.PixelFormats.Rgba32.Red)); - Assert.False(new GraphicsOptions(true).IsOpaqueColorWithoutBlending(ImageSharp.PixelFormats.Rgba32.Transparent)); - Assert.False(new GraphicsOptions(true, PixelColorBlendingMode.Lighten, 1).IsOpaqueColorWithoutBlending(ImageSharp.PixelFormats.Rgba32.Red)); - Assert.False(new GraphicsOptions(true, PixelColorBlendingMode.Normal, PixelAlphaCompositionMode.DestOver, 1).IsOpaqueColorWithoutBlending(ImageSharp.PixelFormats.Rgba32.Red)); + Assert.True(new GraphicsOptions(true).IsOpaqueColorWithoutBlending(Rgba32.Red)); + Assert.False(new GraphicsOptions(true, 0.5f).IsOpaqueColorWithoutBlending(Rgba32.Red)); + Assert.False(new GraphicsOptions(true).IsOpaqueColorWithoutBlending(Rgba32.Transparent)); + Assert.False(new GraphicsOptions(true, PixelColorBlendingMode.Lighten, 1).IsOpaqueColorWithoutBlending(Rgba32.Red)); + Assert.False(new GraphicsOptions(true, PixelColorBlendingMode.Normal, PixelAlphaCompositionMode.DestOver, 1).IsOpaqueColorWithoutBlending(Rgba32.Red)); } } @@ -106,7 +366,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats public static TheoryData ArraySizesData => new TheoryData { 7, 16, 1111 }; - private static PixelOperations Operations => PixelOperations.Instance; + internal static PixelOperations Operations => PixelOperations.Instance; internal static TPixel[] CreateExpectedPixelData(Vector4[] source) { @@ -210,383 +470,333 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromRgb24Bytes(int count) + public void PackFromArgb32Bytes(int count) { - byte[] source = CreateByteTestData(count * 3); + byte[] source = CreateByteTestData(count * 4); var expected = new TPixel[count]; for (int i = 0; i < count; i++) { - int i3 = i * 3; + int i4 = i * 4; - expected[i].PackFromRgba32(new Rgba32(source[i3 + 0], source[i3 + 1], source[i3 + 2], 255)); + expected[i].PackFromArgb32(new Argb32(source[i4 + 1], source[i4 + 2], source[i4 + 3], source[i4 + 0])); } TestOperation( source, expected, - (s, d) => Operations.PackFromRgb24Bytes(s, d.GetSpan(), count) + (s, d) => Operations.PackFromArgb32Bytes(s, d.GetSpan(), count) ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void ToRgb24Bytes(int count) + public void ToArgb32Bytes(int count) { TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 3]; - var rgb = default(Rgb24); + byte[] expected = new byte[count * 4]; + var argb = default(Argb32); for (int i = 0; i < count; i++) { - int i3 = i * 3; - rgb.PackFromScaledVector4(source[i].ToScaledVector4()); - expected[i3] = rgb.R; - expected[i3 + 1] = rgb.G; - expected[i3 + 2] = rgb.B; + int i4 = i * 4; + argb.PackFromScaledVector4(source[i].ToScaledVector4()); + + expected[i4] = argb.A; + expected[i4 + 1] = argb.R; + expected[i4 + 2] = argb.G; + expected[i4 + 3] = argb.B; } TestOperation( source, expected, - (s, d) => Operations.ToRgb24Bytes(s, d.GetSpan(), count) + (s, d) => Operations.ToArgb32Bytes(s, d.GetSpan(), count) ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromRgba32Bytes(int count) + public void PackFromBgr24Bytes(int count) { - byte[] source = CreateByteTestData(count * 4); + byte[] source = CreateByteTestData(count * 3); var expected = new TPixel[count]; for (int i = 0; i < count; i++) { - int i4 = i * 4; + int i3 = i * 3; - expected[i].PackFromRgba32(new Rgba32(source[i4 + 0], source[i4 + 1], source[i4 + 2], source[i4 + 3])); + expected[i].PackFromBgr24(new Bgr24(source[i3 + 2], source[i3 + 1], source[i3])); } TestOperation( source, expected, - (s, d) => Operations.PackFromRgba32Bytes(s, d.GetSpan(), count) + (s, d) => Operations.PackFromBgr24Bytes(s, d.GetSpan(), count) ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void ToRgba32Bytes(int count) + public void ToBgr24Bytes(int count) { TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 4]; - var rgba = default(Rgba32); + byte[] expected = new byte[count * 3]; + var bgr = default(Bgr24); for (int i = 0; i < count; i++) { - int i4 = i * 4; - rgba.PackFromScaledVector4(source[i].ToScaledVector4()); - expected[i4] = rgba.R; - expected[i4 + 1] = rgba.G; - expected[i4 + 2] = rgba.B; - expected[i4 + 3] = rgba.A; + int i3 = i * 3; + bgr.PackFromScaledVector4(source[i].ToScaledVector4()); + expected[i3] = bgr.B; + expected[i3 + 1] = bgr.G; + expected[i3 + 2] = bgr.R; } TestOperation( source, expected, - (s, d) => Operations.ToRgba32Bytes(s, d.GetSpan(), count) + (s, d) => Operations.ToBgr24Bytes(s, d.GetSpan(), count) ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromRgb48Bytes(int count) + public void PackFromBgra32Bytes(int count) { - byte[] source = CreateByteTestData(count * 6); - Span sourceSpan = source.AsSpan(); + byte[] source = CreateByteTestData(count * 4); var expected = new TPixel[count]; - var rgba64 = new Rgba64(0, 0, 0, 65535); for (int i = 0; i < count; i++) { - int i6 = i * 6; - rgba64.Rgb = MemoryMarshal.Cast(sourceSpan.Slice(i6, 6))[0]; - expected[i].PackFromRgba64(rgba64); + int i4 = i * 4; + + expected[i].PackFromBgra32(new Bgra32(source[i4 + 2], source[i4 + 1], source[i4 + 0], source[i4 + 3])); } TestOperation( source, expected, - (s, d) => Operations.PackFromRgb48Bytes(s, d.GetSpan(), count) + (s, d) => Operations.PackFromBgra32Bytes(s, d.GetSpan(), count) ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void ToRgb48Bytes(int count) + public void ToBgra32Bytes(int count) { TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 6]; - Rgb48 rgb = default; + byte[] expected = new byte[count * 4]; + var bgra = default(Bgra32); for (int i = 0; i < count; i++) { - int i6 = i * 6; - rgb.PackFromScaledVector4(source[i].ToScaledVector4()); - Rgba64Bytes rgb48Bytes = Unsafe.As(ref rgb); - expected[i6] = rgb48Bytes[0]; - expected[i6 + 1] = rgb48Bytes[1]; - expected[i6 + 2] = rgb48Bytes[2]; - expected[i6 + 3] = rgb48Bytes[3]; - expected[i6 + 4] = rgb48Bytes[4]; - expected[i6 + 5] = rgb48Bytes[5]; + int i4 = i * 4; + bgra.PackFromScaledVector4(source[i].ToScaledVector4()); + expected[i4] = bgra.B; + expected[i4 + 1] = bgra.G; + expected[i4 + 2] = bgra.R; + expected[i4 + 3] = bgra.A; } TestOperation( source, expected, - (s, d) => Operations.ToRgb48Bytes(s, d.GetSpan(), count) + (s, d) => Operations.ToBgra32Bytes(s, d.GetSpan(), count) ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromRgba64Bytes(int count) + public void PackFromRgb24Bytes(int count) { - byte[] source = CreateByteTestData(count * 8); - Span sourceSpan = source.AsSpan(); + byte[] source = CreateByteTestData(count * 3); var expected = new TPixel[count]; for (int i = 0; i < count; i++) { - int i8 = i * 8; - expected[i].PackFromRgba64(MemoryMarshal.Cast(sourceSpan.Slice(i8, 8))[0]); + int i3 = i * 3; + + expected[i].PackFromRgb24(new Rgb24(source[i3 + 0], source[i3 + 1], source[i3 + 2])); } TestOperation( source, expected, - (s, d) => Operations.PackFromRgba64Bytes(s, d.GetSpan(), count) + (s, d) => Operations.PackFromRgb24Bytes(s, d.GetSpan(), count) ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void ToRgba64Bytes(int count) + public void ToRgb24Bytes(int count) { TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 8]; - Rgba64 rgba = default; + byte[] expected = new byte[count * 3]; + var rgb = default(Rgb24); for (int i = 0; i < count; i++) { - int i8 = i * 8; - rgba.PackFromScaledVector4(source[i].ToScaledVector4()); - Rgba64Bytes rgba64Bytes = Unsafe.As(ref rgba); - expected[i8] = rgba64Bytes[0]; - expected[i8 + 1] = rgba64Bytes[1]; - expected[i8 + 2] = rgba64Bytes[2]; - expected[i8 + 3] = rgba64Bytes[3]; - expected[i8 + 4] = rgba64Bytes[4]; - expected[i8 + 5] = rgba64Bytes[5]; - expected[i8 + 6] = rgba64Bytes[6]; - expected[i8 + 7] = rgba64Bytes[7]; + int i3 = i * 3; + rgb.PackFromScaledVector4(source[i].ToScaledVector4()); + expected[i3] = rgb.R; + expected[i3 + 1] = rgb.G; + expected[i3 + 2] = rgb.B; } TestOperation( source, expected, - (s, d) => Operations.ToRgba64Bytes(s, d.GetSpan(), count) + (s, d) => Operations.ToRgb24Bytes(s, d.GetSpan(), count) ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromBgr24Bytes(int count) + public void PackFromRgba32Bytes(int count) { - byte[] source = CreateByteTestData(count * 3); + byte[] source = CreateByteTestData(count * 4); var expected = new TPixel[count]; for (int i = 0; i < count; i++) { - int i3 = i * 3; + int i4 = i * 4; - expected[i].PackFromRgba32(new Rgba32(source[i3 + 2], source[i3 + 1], source[i3 + 0], 255)); + expected[i].PackFromRgba32(new Rgba32(source[i4 + 0], source[i4 + 1], source[i4 + 2], source[i4 + 3])); } TestOperation( source, expected, - (s, d) => Operations.PackFromBgr24Bytes(s, d.GetSpan(), count) + (s, d) => Operations.PackFromRgba32Bytes(s, d.GetSpan(), count) ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void ToBgr24Bytes(int count) + public void ToRgba32Bytes(int count) { TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 3]; - var bgr = default(Bgr24); + byte[] expected = new byte[count * 4]; + var rgba = default(Rgba32); for (int i = 0; i < count; i++) { - int i3 = i * 3; - bgr.PackFromScaledVector4(source[i].ToScaledVector4()); - expected[i3] = bgr.B; - expected[i3 + 1] = bgr.G; - expected[i3 + 2] = bgr.R; + int i4 = i * 4; + rgba.PackFromScaledVector4(source[i].ToScaledVector4()); + expected[i4] = rgba.R; + expected[i4 + 1] = rgba.G; + expected[i4 + 2] = rgba.B; + expected[i4 + 3] = rgba.A; } TestOperation( source, expected, - (s, d) => Operations.ToBgr24Bytes(s, d.GetSpan(), count) + (s, d) => Operations.ToRgba32Bytes(s, d.GetSpan(), count) ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromBgra32Bytes(int count) + public void PackFromRgb48Bytes(int count) { - byte[] source = CreateByteTestData(count * 4); + byte[] source = CreateByteTestData(count * 6); + Span sourceSpan = source.AsSpan(); var expected = new TPixel[count]; for (int i = 0; i < count; i++) { - int i4 = i * 4; - - expected[i].PackFromRgba32(new Rgba32(source[i4 + 2], source[i4 + 1], source[i4 + 0], source[i4 + 3])); + int i6 = i * 6; + expected[i].PackFromRgb48(MemoryMarshal.Cast(sourceSpan.Slice(i6, 6))[0]); } TestOperation( source, expected, - (s, d) => Operations.PackFromBgra32Bytes(s, d.GetSpan(), count) + (s, d) => Operations.PackFromRgb48Bytes(s, d.GetSpan(), count) ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void ToBgra32Bytes(int count) + public void ToRgb48Bytes(int count) { TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 4]; - var bgra = default(Bgra32); + byte[] expected = new byte[count * 6]; + Rgb48 rgb = default; for (int i = 0; i < count; i++) { - int i4 = i * 4; - bgra.PackFromScaledVector4(source[i].ToScaledVector4()); - expected[i4] = bgra.B; - expected[i4 + 1] = bgra.G; - expected[i4 + 2] = bgra.R; - expected[i4 + 3] = bgra.A; + int i6 = i * 6; + rgb.PackFromScaledVector4(source[i].ToScaledVector4()); + OctetBytes rgb48Bytes = Unsafe.As(ref rgb); + expected[i6] = rgb48Bytes[0]; + expected[i6 + 1] = rgb48Bytes[1]; + expected[i6 + 2] = rgb48Bytes[2]; + expected[i6 + 3] = rgb48Bytes[3]; + expected[i6 + 4] = rgb48Bytes[4]; + expected[i6 + 5] = rgb48Bytes[5]; } TestOperation( source, expected, - (s, d) => Operations.ToBgra32Bytes(s, d.GetSpan(), count) + (s, d) => Operations.ToRgb48Bytes(s, d.GetSpan(), count) ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void PackFromArgb32Bytes(int count) + public void PackFromRgba64Bytes(int count) { - byte[] source = CreateByteTestData(count * 4); + byte[] source = CreateByteTestData(count * 8); + Span sourceSpan = source.AsSpan(); var expected = new TPixel[count]; for (int i = 0; i < count; i++) { - int i4 = i * 4; - - expected[i].PackFromRgba32(new Rgba32(source[i4 + 1], source[i4 + 2], source[i4 + 3], source[i4 + 0])); + int i8 = i * 8; + expected[i].PackFromRgba64(MemoryMarshal.Cast(sourceSpan.Slice(i8, 8))[0]); } TestOperation( source, expected, - (s, d) => Operations.PackFromArgb32Bytes(s, d.GetSpan(), count) + (s, d) => Operations.PackFromRgba64Bytes(s, d.GetSpan(), count) ); } [Theory] [MemberData(nameof(ArraySizesData))] - public void ToArgb32Bytes(int count) + public void ToRgba64Bytes(int count) { TPixel[] source = CreatePixelTestData(count); - byte[] expected = new byte[count * 4]; - var argb = default(Argb32); + byte[] expected = new byte[count * 8]; + Rgba64 rgba = default; for (int i = 0; i < count; i++) { - int i4 = i * 4; - argb.PackFromScaledVector4(source[i].ToScaledVector4()); - - expected[i4] = argb.A; - expected[i4 + 1] = argb.R; - expected[i4 + 2] = argb.G; - expected[i4 + 3] = argb.B; + int i8 = i * 8; + rgba.PackFromScaledVector4(source[i].ToScaledVector4()); + OctetBytes rgba64Bytes = Unsafe.As(ref rgba); + expected[i8] = rgba64Bytes[0]; + expected[i8 + 1] = rgba64Bytes[1]; + expected[i8 + 2] = rgba64Bytes[2]; + expected[i8 + 3] = rgba64Bytes[3]; + expected[i8 + 4] = rgba64Bytes[4]; + expected[i8 + 5] = rgba64Bytes[5]; + expected[i8 + 6] = rgba64Bytes[6]; + expected[i8 + 7] = rgba64Bytes[7]; } TestOperation( source, expected, - (s, d) => Operations.ToArgb32Bytes(s, d.GetSpan(), count) + (s, d) => Operations.ToRgba64Bytes(s, d.GetSpan(), count) ); } - private class TestBuffers : IDisposable - where TSource : struct - where TDest : struct - { - public TSource[] SourceBuffer { get; } - public IMemoryOwner ActualDestBuffer { get; } - public TDest[] ExpectedDestBuffer { get; } - - public TestBuffers(TSource[] source, TDest[] expectedDest) - { - this.SourceBuffer = source; - this.ExpectedDestBuffer = expectedDest; - this.ActualDestBuffer = Configuration.Default.MemoryAllocator.Allocate(expectedDest.Length); - } - - public void Dispose() => this.ActualDestBuffer.Dispose(); - - private const float Tolerance = 0.0001f; - - public void Verify() - { - int count = this.ExpectedDestBuffer.Length; - - if (typeof(TDest) == typeof(Vector4)) - { - - Span expected = MemoryMarshal.Cast(this.ExpectedDestBuffer.AsSpan()); - Span actual = MemoryMarshal.Cast(this.ActualDestBuffer.GetSpan()); - - for (int i = 0; i < count; i++) - { - // ReSharper disable PossibleNullReferenceException - Assert.Equal(expected[i], actual[i], new ApproximateFloatComparer(0.001f)); - // ReSharper restore PossibleNullReferenceException - } - } - else - { - Span expected = this.ExpectedDestBuffer.AsSpan(); - Span actual = this.ActualDestBuffer.GetSpan(); - for (int i = 0; i < count; i++) - { - Assert.Equal(expected[i], actual[i]); - } - } - } - } - internal static void TestOperation( TSource[] source, TDest[] expected, @@ -666,7 +876,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } [StructLayout(LayoutKind.Sequential)] - private unsafe struct Rgba64Bytes + internal unsafe struct OctetBytes { public fixed byte Data[8]; @@ -675,10 +885,56 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - ref byte self = ref Unsafe.As(ref this); + ref byte self = ref Unsafe.As(ref this); return Unsafe.Add(ref self, idx); } } } + + private class TestBuffers : IDisposable + where TSource : struct + where TDest : struct + { + public TSource[] SourceBuffer { get; } + public IMemoryOwner ActualDestBuffer { get; } + public TDest[] ExpectedDestBuffer { get; } + + public TestBuffers(TSource[] source, TDest[] expectedDest) + { + this.SourceBuffer = source; + this.ExpectedDestBuffer = expectedDest; + this.ActualDestBuffer = Configuration.Default.MemoryAllocator.Allocate(expectedDest.Length); + } + + public void Dispose() => this.ActualDestBuffer.Dispose(); + + public void Verify() + { + int count = this.ExpectedDestBuffer.Length; + + if (typeof(TDest) == typeof(Vector4)) + { + Span expected = MemoryMarshal.Cast(this.ExpectedDestBuffer.AsSpan()); + Span actual = MemoryMarshal.Cast(this.ActualDestBuffer.GetSpan()); + + var comparer = new ApproximateFloatComparer(0.001f); + for (int i = 0; i < count; i++) + { + // ReSharper disable PossibleNullReferenceException + Assert.Equal(expected[i], actual[i], comparer); + // ReSharper restore PossibleNullReferenceException + } + } + else + { + Span expected = this.ExpectedDestBuffer.AsSpan(); + Span actual = this.ActualDestBuffer.GetSpan(); + for (int i = 0; i < count; i++) + { + Assert.Equal(expected[i], actual[i]); + } + } + } + } } } \ No newline at end of file