mirror of https://github.com/SixLabors/ImageSharp
committed by
GitHub
71 changed files with 2129 additions and 151 deletions
@ -0,0 +1,396 @@ |
|||||
|
// Copyright (c) Six Labors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System; |
||||
|
using System.Numerics; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
using System.Runtime.InteropServices; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.PixelFormats |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Packed pixel type containing four 8-bit unsigned normalized values ranging from 0 to 255.
|
||||
|
/// The color components are stored in alpha, red, green, and blue order (least significant to most significant byte).
|
||||
|
/// <para>
|
||||
|
/// Ranges from [0, 0, 0, 0] to [1, 1, 1, 1] in vector form.
|
||||
|
/// </para>
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// This struct is fully mutable. This is done (against the guidelines) for the sake of performance,
|
||||
|
/// as it avoids the need to create new values for modification operations.
|
||||
|
/// </remarks>
|
||||
|
[StructLayout(LayoutKind.Sequential)] |
||||
|
public partial struct Abgr32 : IPixel<Abgr32>, IPackedVector<uint> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Gets or sets the alpha component.
|
||||
|
/// </summary>
|
||||
|
public byte A; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets the blue component.
|
||||
|
/// </summary>
|
||||
|
public byte B; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets the green component.
|
||||
|
/// </summary>
|
||||
|
public byte G; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets the red component.
|
||||
|
/// </summary>
|
||||
|
public byte R; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The maximum byte value.
|
||||
|
/// </summary>
|
||||
|
private static readonly Vector4 MaxBytes = new(255); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The half vector value.
|
||||
|
/// </summary>
|
||||
|
private static readonly Vector4 Half = new(0.5F); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="Abgr32"/> struct.
|
||||
|
/// </summary>
|
||||
|
/// <param name="r">The red component.</param>
|
||||
|
/// <param name="g">The green component.</param>
|
||||
|
/// <param name="b">The blue component.</param>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public Abgr32(byte r, byte g, byte b) |
||||
|
{ |
||||
|
this.R = r; |
||||
|
this.G = g; |
||||
|
this.B = b; |
||||
|
this.A = byte.MaxValue; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="Abgr32"/> struct.
|
||||
|
/// </summary>
|
||||
|
/// <param name="r">The red component.</param>
|
||||
|
/// <param name="g">The green component.</param>
|
||||
|
/// <param name="b">The blue component.</param>
|
||||
|
/// <param name="a">The alpha component.</param>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public Abgr32(byte r, byte g, byte b, byte a) |
||||
|
{ |
||||
|
this.R = r; |
||||
|
this.G = g; |
||||
|
this.B = b; |
||||
|
this.A = a; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="Abgr32"/> struct.
|
||||
|
/// </summary>
|
||||
|
/// <param name="r">The red component.</param>
|
||||
|
/// <param name="g">The green component.</param>
|
||||
|
/// <param name="b">The blue component.</param>
|
||||
|
/// <param name="a">The alpha component.</param>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public Abgr32(float r, float g, float b, float a = 1) |
||||
|
: this() => this.Pack(r, g, b, a); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="Abgr32"/> struct.
|
||||
|
/// </summary>
|
||||
|
/// <param name="vector">
|
||||
|
/// The vector containing the components for the packed vector.
|
||||
|
/// </param>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public Abgr32(Vector3 vector) |
||||
|
: this() => this.Pack(ref vector); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="Abgr32"/> struct.
|
||||
|
/// </summary>
|
||||
|
/// <param name="vector">
|
||||
|
/// The vector containing the components for the packed vector.
|
||||
|
/// </param>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public Abgr32(Vector4 vector) |
||||
|
: this() => this.Pack(ref vector); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="Abgr32"/> struct.
|
||||
|
/// </summary>
|
||||
|
/// <param name="packed">
|
||||
|
/// The packed value.
|
||||
|
/// </param>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public Abgr32(uint packed) |
||||
|
: this() => this.Abgr = packed; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets or sets the packed representation of the Abgrb32 struct.
|
||||
|
/// </summary>
|
||||
|
public uint Abgr |
||||
|
{ |
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
readonly get => Unsafe.As<Abgr32, uint>(ref Unsafe.AsRef(this)); |
||||
|
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
set => Unsafe.As<Abgr32, uint>(ref this) = value; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public uint PackedValue |
||||
|
{ |
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
readonly get => this.Abgr; |
||||
|
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
set => this.Abgr = value; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts an <see cref="Abgr32"/> to <see cref="Color"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The <see cref="Abgr32"/>.</param>
|
||||
|
/// <returns>The <see cref="Color"/>.</returns>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public static implicit operator Color(Abgr32 source) => new(source); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts a <see cref="Color"/> to <see cref="Abgr32"/>.
|
||||
|
/// </summary>
|
||||
|
/// <param name="color">The <see cref="Color"/>.</param>
|
||||
|
/// <returns>The <see cref="Abgr32"/>.</returns>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public static implicit operator Abgr32(Color color) => color.ToAbgr32(); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Compares two <see cref="Argb32"/> objects for equality.
|
||||
|
/// </summary>
|
||||
|
/// <param name="left">The <see cref="Abgr32"/> on the left side of the operand.</param>
|
||||
|
/// <param name="right">The <see cref="Abgr32"/> on the right side of the operand.</param>
|
||||
|
/// <returns>
|
||||
|
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
|
||||
|
/// </returns>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public static bool operator ==(Abgr32 left, Abgr32 right) => left.Equals(right); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Compares two <see cref="Abgr32"/> objects for equality.
|
||||
|
/// </summary>
|
||||
|
/// <param name="left">The <see cref="Abgr32"/> on the left side of the operand.</param>
|
||||
|
/// <param name="right">The <see cref="Abgr32"/> on the right side of the operand.</param>
|
||||
|
/// <returns>
|
||||
|
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
|
||||
|
/// </returns>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public static bool operator !=(Abgr32 left, Abgr32 right) => !left.Equals(right); |
||||
|
|
||||
|
/// <inheritdoc />
|
||||
|
public readonly PixelOperations<Abgr32> CreatePixelOperations() => new PixelOperations(); |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public void FromScaledVector4(Vector4 vector) => this.FromVector4(vector); |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public readonly Vector4 ToScaledVector4() => this.ToVector4(); |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public void FromVector4(Vector4 vector) => this.Pack(ref vector); |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public readonly Vector4 ToVector4() => new Vector4(this.R, this.G, this.B, this.A) / MaxBytes; |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public void FromAbgr32(Abgr32 source) => this = source; |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4()); |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public void FromBgr24(Bgr24 source) |
||||
|
{ |
||||
|
// We can assign the Bgr24 value directly to last three bytes of this instance.
|
||||
|
ref byte thisRef = ref Unsafe.As<Abgr32, byte>(ref this); |
||||
|
ref byte thisRefFromB = ref Unsafe.AddByteOffset(ref thisRef, new IntPtr(1)); |
||||
|
Unsafe.As<byte, Bgr24>(ref thisRefFromB) = source; |
||||
|
this.A = byte.MaxValue; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public void FromArgb32(Argb32 source) |
||||
|
{ |
||||
|
this.R = source.R; |
||||
|
this.G = source.G; |
||||
|
this.B = source.B; |
||||
|
this.A = source.A; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public void FromBgra32(Bgra32 source) |
||||
|
{ |
||||
|
this.R = source.R; |
||||
|
this.G = source.G; |
||||
|
this.B = source.B; |
||||
|
this.A = source.A; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public void FromL8(L8 source) |
||||
|
{ |
||||
|
this.R = source.PackedValue; |
||||
|
this.G = source.PackedValue; |
||||
|
this.B = source.PackedValue; |
||||
|
this.A = byte.MaxValue; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public void FromL16(L16 source) |
||||
|
{ |
||||
|
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(source.PackedValue); |
||||
|
this.R = rgb; |
||||
|
this.G = rgb; |
||||
|
this.B = rgb; |
||||
|
this.A = byte.MaxValue; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public void FromLa16(La16 source) |
||||
|
{ |
||||
|
this.R = source.L; |
||||
|
this.G = source.L; |
||||
|
this.B = source.L; |
||||
|
this.A = source.A; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public void FromLa32(La32 source) |
||||
|
{ |
||||
|
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(source.L); |
||||
|
this.R = rgb; |
||||
|
this.G = rgb; |
||||
|
this.B = rgb; |
||||
|
this.A = ColorNumerics.DownScaleFrom16BitTo8Bit(source.A); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public void FromRgb24(Rgb24 source) |
||||
|
{ |
||||
|
this.R = source.R; |
||||
|
this.G = source.G; |
||||
|
this.B = source.B; |
||||
|
this.A = byte.MaxValue; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public void FromRgba32(Rgba32 source) |
||||
|
{ |
||||
|
this.R = source.R; |
||||
|
this.G = source.G; |
||||
|
this.B = source.B; |
||||
|
this.A = source.A; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc />
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public void ToRgba32(ref Rgba32 dest) |
||||
|
{ |
||||
|
dest.R = this.R; |
||||
|
dest.G = this.G; |
||||
|
dest.B = this.B; |
||||
|
dest.A = this.A; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public void FromRgb48(Rgb48 source) |
||||
|
{ |
||||
|
this.R = ColorNumerics.DownScaleFrom16BitTo8Bit(source.R); |
||||
|
this.G = ColorNumerics.DownScaleFrom16BitTo8Bit(source.G); |
||||
|
this.B = ColorNumerics.DownScaleFrom16BitTo8Bit(source.B); |
||||
|
this.A = byte.MaxValue; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public void FromRgba64(Rgba64 source) |
||||
|
{ |
||||
|
this.R = ColorNumerics.DownScaleFrom16BitTo8Bit(source.R); |
||||
|
this.G = ColorNumerics.DownScaleFrom16BitTo8Bit(source.G); |
||||
|
this.B = ColorNumerics.DownScaleFrom16BitTo8Bit(source.B); |
||||
|
this.A = ColorNumerics.DownScaleFrom16BitTo8Bit(source.A); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public override readonly bool Equals(object obj) => obj is Abgr32 abgr32 && this.Equals(abgr32); |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public readonly bool Equals(Abgr32 other) => this.Abgr == other.Abgr; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets a string representation of the packed vector.
|
||||
|
/// </summary>
|
||||
|
/// <returns>A string representation of the packed vector.</returns>
|
||||
|
public override readonly string ToString() => $"Abgr({this.A}, {this.B}, {this.G}, {this.R})"; |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
public override readonly int GetHashCode() => this.Abgr.GetHashCode(); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Packs the four floats into a color.
|
||||
|
/// </summary>
|
||||
|
/// <param name="x">The x-component</param>
|
||||
|
/// <param name="y">The y-component</param>
|
||||
|
/// <param name="z">The z-component</param>
|
||||
|
/// <param name="w">The w-component</param>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
private void Pack(float x, float y, float z, float w) |
||||
|
{ |
||||
|
var value = new Vector4(x, y, z, w); |
||||
|
this.Pack(ref value); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Packs a <see cref="Vector3"/> into a uint.
|
||||
|
/// </summary>
|
||||
|
/// <param name="vector">The vector containing the values to pack.</param>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
private void Pack(ref Vector3 vector) |
||||
|
{ |
||||
|
var value = new Vector4(vector, 1); |
||||
|
this.Pack(ref value); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Packs a <see cref="Vector4"/> into a color.
|
||||
|
/// </summary>
|
||||
|
/// <param name="vector">The vector containing the values to pack.</param>
|
||||
|
[MethodImpl(InliningOptions.ShortMethod)] |
||||
|
private void Pack(ref Vector4 vector) |
||||
|
{ |
||||
|
vector *= MaxBytes; |
||||
|
vector += Half; |
||||
|
vector = Numerics.Clamp(vector, Vector4.Zero, MaxBytes); |
||||
|
|
||||
|
this.R = (byte)vector.X; |
||||
|
this.G = (byte)vector.Y; |
||||
|
this.B = (byte)vector.Z; |
||||
|
this.A = (byte)vector.W; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,26 @@ |
|||||
|
// Copyright (c) Six Labors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System; |
||||
|
using SixLabors.ImageSharp.Formats; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.PixelFormats |
||||
|
{ |
||||
|
/// <content>
|
||||
|
/// Provides optimized overrides for bulk operations.
|
||||
|
/// </content>
|
||||
|
public partial struct Abgr32 |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Provides optimized overrides for bulk operations.
|
||||
|
/// </summary>
|
||||
|
internal partial class PixelOperations : PixelOperations<Abgr32> |
||||
|
{ |
||||
|
private static readonly Lazy<PixelTypeInfo> LazyInfo = |
||||
|
new Lazy<PixelTypeInfo>(() => PixelTypeInfo.Create<Abgr32>(PixelAlphaRepresentation.Unassociated), true); |
||||
|
|
||||
|
/// <inheritdoc />
|
||||
|
public override PixelTypeInfo GetPixelTypeInfo() => LazyInfo.Value; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,346 @@ |
|||||
|
// Copyright (c) Six Labors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
// <auto-generated />
|
||||
|
|
||||
|
using System; |
||||
|
using System.Numerics; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
using System.Runtime.InteropServices; |
||||
|
using SixLabors.ImageSharp.PixelFormats.Utils; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.PixelFormats |
||||
|
{ |
||||
|
/// <content>
|
||||
|
/// Provides optimized overrides for bulk operations.
|
||||
|
/// </content>
|
||||
|
public partial struct Abgr32 |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Provides optimized overrides for bulk operations.
|
||||
|
/// </summary>
|
||||
|
internal partial class PixelOperations : PixelOperations<Abgr32> |
||||
|
{ |
||||
|
/// <inheritdoc />
|
||||
|
public override void FromAbgr32(Configuration configuration, ReadOnlySpan<Abgr32> source, Span<Abgr32> destinationPixels) |
||||
|
{ |
||||
|
Guard.NotNull(configuration, nameof(configuration)); |
||||
|
Guard.DestinationShouldNotBeTooShort(source, destinationPixels, nameof(destinationPixels)); |
||||
|
|
||||
|
source.CopyTo(destinationPixels.Slice(0, source.Length)); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc />
|
||||
|
public override void ToAbgr32(Configuration configuration, ReadOnlySpan<Abgr32> sourcePixels, Span<Abgr32> destinationPixels) |
||||
|
{ |
||||
|
Guard.NotNull(configuration, nameof(configuration)); |
||||
|
Guard.DestinationShouldNotBeTooShort(sourcePixels, destinationPixels, nameof(destinationPixels)); |
||||
|
|
||||
|
sourcePixels.CopyTo(destinationPixels.Slice(0, sourcePixels.Length)); |
||||
|
} |
||||
|
/// <inheritdoc />
|
||||
|
public override void FromVector4Destructive( |
||||
|
Configuration configuration, |
||||
|
Span<Vector4> sourceVectors, |
||||
|
Span<Abgr32> destinationPixels, |
||||
|
PixelConversionModifiers modifiers) |
||||
|
{ |
||||
|
Vector4Converters.RgbaCompatible.FromVector4(configuration, this, sourceVectors, destinationPixels, modifiers.Remove(PixelConversionModifiers.Scale)); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc />
|
||||
|
public override void ToVector4( |
||||
|
Configuration configuration, |
||||
|
ReadOnlySpan<Abgr32> sourcePixels, |
||||
|
Span<Vector4> destVectors, |
||||
|
PixelConversionModifiers modifiers) |
||||
|
{ |
||||
|
Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, modifiers.Remove(PixelConversionModifiers.Scale)); |
||||
|
} |
||||
|
/// <inheritdoc />
|
||||
|
public override void ToRgba32( |
||||
|
Configuration configuration, |
||||
|
ReadOnlySpan<Abgr32> sourcePixels, |
||||
|
Span<Rgba32> destinationPixels) |
||||
|
{ |
||||
|
Guard.NotNull(configuration, nameof(configuration)); |
||||
|
Guard.DestinationShouldNotBeTooShort(sourcePixels, destinationPixels, nameof(destinationPixels)); |
||||
|
|
||||
|
ReadOnlySpan<byte> source = MemoryMarshal.Cast<Abgr32, byte>(sourcePixels); |
||||
|
Span<byte> dest = MemoryMarshal.Cast<Rgba32, byte>(destinationPixels); |
||||
|
PixelConverter.FromAbgr32.ToRgba32(source, dest); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc />
|
||||
|
public override void FromRgba32( |
||||
|
Configuration configuration, |
||||
|
ReadOnlySpan<Rgba32> sourcePixels, |
||||
|
Span<Abgr32> destinationPixels) |
||||
|
{ |
||||
|
Guard.NotNull(configuration, nameof(configuration)); |
||||
|
Guard.DestinationShouldNotBeTooShort(sourcePixels, destinationPixels, nameof(destinationPixels)); |
||||
|
|
||||
|
ReadOnlySpan<byte> source = MemoryMarshal.Cast<Rgba32, byte>(sourcePixels); |
||||
|
Span<byte> dest = MemoryMarshal.Cast<Abgr32, byte>(destinationPixels); |
||||
|
PixelConverter.FromRgba32.ToAbgr32(source, dest); |
||||
|
} |
||||
|
/// <inheritdoc />
|
||||
|
public override void ToArgb32( |
||||
|
Configuration configuration, |
||||
|
ReadOnlySpan<Abgr32> sourcePixels, |
||||
|
Span<Argb32> destinationPixels) |
||||
|
{ |
||||
|
Guard.NotNull(configuration, nameof(configuration)); |
||||
|
Guard.DestinationShouldNotBeTooShort(sourcePixels, destinationPixels, nameof(destinationPixels)); |
||||
|
|
||||
|
ReadOnlySpan<byte> source = MemoryMarshal.Cast<Abgr32, byte>(sourcePixels); |
||||
|
Span<byte> dest = MemoryMarshal.Cast<Argb32, byte>(destinationPixels); |
||||
|
PixelConverter.FromAbgr32.ToArgb32(source, dest); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc />
|
||||
|
public override void FromArgb32( |
||||
|
Configuration configuration, |
||||
|
ReadOnlySpan<Argb32> sourcePixels, |
||||
|
Span<Abgr32> destinationPixels) |
||||
|
{ |
||||
|
Guard.NotNull(configuration, nameof(configuration)); |
||||
|
Guard.DestinationShouldNotBeTooShort(sourcePixels, destinationPixels, nameof(destinationPixels)); |
||||
|
|
||||
|
ReadOnlySpan<byte> source = MemoryMarshal.Cast<Argb32, byte>(sourcePixels); |
||||
|
Span<byte> dest = MemoryMarshal.Cast<Abgr32, byte>(destinationPixels); |
||||
|
PixelConverter.FromArgb32.ToAbgr32(source, dest); |
||||
|
} |
||||
|
/// <inheritdoc />
|
||||
|
public override void ToBgra32( |
||||
|
Configuration configuration, |
||||
|
ReadOnlySpan<Abgr32> sourcePixels, |
||||
|
Span<Bgra32> destinationPixels) |
||||
|
{ |
||||
|
Guard.NotNull(configuration, nameof(configuration)); |
||||
|
Guard.DestinationShouldNotBeTooShort(sourcePixels, destinationPixels, nameof(destinationPixels)); |
||||
|
|
||||
|
ReadOnlySpan<byte> source = MemoryMarshal.Cast<Abgr32, byte>(sourcePixels); |
||||
|
Span<byte> dest = MemoryMarshal.Cast<Bgra32, byte>(destinationPixels); |
||||
|
PixelConverter.FromAbgr32.ToBgra32(source, dest); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc />
|
||||
|
public override void FromBgra32( |
||||
|
Configuration configuration, |
||||
|
ReadOnlySpan<Bgra32> sourcePixels, |
||||
|
Span<Abgr32> destinationPixels) |
||||
|
{ |
||||
|
Guard.NotNull(configuration, nameof(configuration)); |
||||
|
Guard.DestinationShouldNotBeTooShort(sourcePixels, destinationPixels, nameof(destinationPixels)); |
||||
|
|
||||
|
ReadOnlySpan<byte> source = MemoryMarshal.Cast<Bgra32, byte>(sourcePixels); |
||||
|
Span<byte> dest = MemoryMarshal.Cast<Abgr32, byte>(destinationPixels); |
||||
|
PixelConverter.FromBgra32.ToAbgr32(source, dest); |
||||
|
} |
||||
|
/// <inheritdoc />
|
||||
|
public override void ToRgb24( |
||||
|
Configuration configuration, |
||||
|
ReadOnlySpan<Abgr32> sourcePixels, |
||||
|
Span<Rgb24> destinationPixels) |
||||
|
{ |
||||
|
Guard.NotNull(configuration, nameof(configuration)); |
||||
|
Guard.DestinationShouldNotBeTooShort(sourcePixels, destinationPixels, nameof(destinationPixels)); |
||||
|
|
||||
|
ReadOnlySpan<byte> source = MemoryMarshal.Cast<Abgr32, byte>(sourcePixels); |
||||
|
Span<byte> dest = MemoryMarshal.Cast<Rgb24, byte>(destinationPixels); |
||||
|
PixelConverter.FromAbgr32.ToRgb24(source, dest); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc />
|
||||
|
public override void FromRgb24( |
||||
|
Configuration configuration, |
||||
|
ReadOnlySpan<Rgb24> sourcePixels, |
||||
|
Span<Abgr32> destinationPixels) |
||||
|
{ |
||||
|
Guard.NotNull(configuration, nameof(configuration)); |
||||
|
Guard.DestinationShouldNotBeTooShort(sourcePixels, destinationPixels, nameof(destinationPixels)); |
||||
|
|
||||
|
ReadOnlySpan<byte> source = MemoryMarshal.Cast<Rgb24, byte>(sourcePixels); |
||||
|
Span<byte> dest = MemoryMarshal.Cast<Abgr32, byte>(destinationPixels); |
||||
|
PixelConverter.FromRgb24.ToAbgr32(source, dest); |
||||
|
} |
||||
|
/// <inheritdoc />
|
||||
|
public override void ToBgr24( |
||||
|
Configuration configuration, |
||||
|
ReadOnlySpan<Abgr32> sourcePixels, |
||||
|
Span<Bgr24> destinationPixels) |
||||
|
{ |
||||
|
Guard.NotNull(configuration, nameof(configuration)); |
||||
|
Guard.DestinationShouldNotBeTooShort(sourcePixels, destinationPixels, nameof(destinationPixels)); |
||||
|
|
||||
|
ReadOnlySpan<byte> source = MemoryMarshal.Cast<Abgr32, byte>(sourcePixels); |
||||
|
Span<byte> dest = MemoryMarshal.Cast<Bgr24, byte>(destinationPixels); |
||||
|
PixelConverter.FromAbgr32.ToBgr24(source, dest); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc />
|
||||
|
public override void FromBgr24( |
||||
|
Configuration configuration, |
||||
|
ReadOnlySpan<Bgr24> sourcePixels, |
||||
|
Span<Abgr32> destinationPixels) |
||||
|
{ |
||||
|
Guard.NotNull(configuration, nameof(configuration)); |
||||
|
Guard.DestinationShouldNotBeTooShort(sourcePixels, destinationPixels, nameof(destinationPixels)); |
||||
|
|
||||
|
ReadOnlySpan<byte> source = MemoryMarshal.Cast<Bgr24, byte>(sourcePixels); |
||||
|
Span<byte> dest = MemoryMarshal.Cast<Abgr32, byte>(destinationPixels); |
||||
|
PixelConverter.FromBgr24.ToAbgr32(source, dest); |
||||
|
} |
||||
|
/// <inheritdoc />
|
||||
|
public override void ToL8( |
||||
|
Configuration configuration, |
||||
|
ReadOnlySpan<Abgr32> sourcePixels, |
||||
|
Span<L8> destinationPixels) |
||||
|
{ |
||||
|
Guard.NotNull(configuration, nameof(configuration)); |
||||
|
Guard.DestinationShouldNotBeTooShort(sourcePixels, destinationPixels, nameof(destinationPixels)); |
||||
|
|
||||
|
ref Abgr32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); |
||||
|
ref L8 destRef = ref MemoryMarshal.GetReference(destinationPixels); |
||||
|
|
||||
|
for (nint i = 0; i < sourcePixels.Length; i++) |
||||
|
{ |
||||
|
ref Abgr32 sp = ref Unsafe.Add(ref sourceRef, i); |
||||
|
ref L8 dp = ref Unsafe.Add(ref destRef, i); |
||||
|
|
||||
|
dp.FromAbgr32(sp); |
||||
|
} |
||||
|
} |
||||
|
/// <inheritdoc />
|
||||
|
public override void ToL16( |
||||
|
Configuration configuration, |
||||
|
ReadOnlySpan<Abgr32> sourcePixels, |
||||
|
Span<L16> destinationPixels) |
||||
|
{ |
||||
|
Guard.NotNull(configuration, nameof(configuration)); |
||||
|
Guard.DestinationShouldNotBeTooShort(sourcePixels, destinationPixels, nameof(destinationPixels)); |
||||
|
|
||||
|
ref Abgr32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); |
||||
|
ref L16 destRef = ref MemoryMarshal.GetReference(destinationPixels); |
||||
|
|
||||
|
for (nint i = 0; i < sourcePixels.Length; i++) |
||||
|
{ |
||||
|
ref Abgr32 sp = ref Unsafe.Add(ref sourceRef, i); |
||||
|
ref L16 dp = ref Unsafe.Add(ref destRef, i); |
||||
|
|
||||
|
dp.FromAbgr32(sp); |
||||
|
} |
||||
|
} |
||||
|
/// <inheritdoc />
|
||||
|
public override void ToLa16( |
||||
|
Configuration configuration, |
||||
|
ReadOnlySpan<Abgr32> sourcePixels, |
||||
|
Span<La16> destinationPixels) |
||||
|
{ |
||||
|
Guard.NotNull(configuration, nameof(configuration)); |
||||
|
Guard.DestinationShouldNotBeTooShort(sourcePixels, destinationPixels, nameof(destinationPixels)); |
||||
|
|
||||
|
ref Abgr32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); |
||||
|
ref La16 destRef = ref MemoryMarshal.GetReference(destinationPixels); |
||||
|
|
||||
|
for (nint i = 0; i < sourcePixels.Length; i++) |
||||
|
{ |
||||
|
ref Abgr32 sp = ref Unsafe.Add(ref sourceRef, i); |
||||
|
ref La16 dp = ref Unsafe.Add(ref destRef, i); |
||||
|
|
||||
|
dp.FromAbgr32(sp); |
||||
|
} |
||||
|
} |
||||
|
/// <inheritdoc />
|
||||
|
public override void ToLa32( |
||||
|
Configuration configuration, |
||||
|
ReadOnlySpan<Abgr32> sourcePixels, |
||||
|
Span<La32> destinationPixels) |
||||
|
{ |
||||
|
Guard.NotNull(configuration, nameof(configuration)); |
||||
|
Guard.DestinationShouldNotBeTooShort(sourcePixels, destinationPixels, nameof(destinationPixels)); |
||||
|
|
||||
|
ref Abgr32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); |
||||
|
ref La32 destRef = ref MemoryMarshal.GetReference(destinationPixels); |
||||
|
|
||||
|
for (nint i = 0; i < sourcePixels.Length; i++) |
||||
|
{ |
||||
|
ref Abgr32 sp = ref Unsafe.Add(ref sourceRef, i); |
||||
|
ref La32 dp = ref Unsafe.Add(ref destRef, i); |
||||
|
|
||||
|
dp.FromAbgr32(sp); |
||||
|
} |
||||
|
} |
||||
|
/// <inheritdoc />
|
||||
|
public override void ToRgb48( |
||||
|
Configuration configuration, |
||||
|
ReadOnlySpan<Abgr32> sourcePixels, |
||||
|
Span<Rgb48> destinationPixels) |
||||
|
{ |
||||
|
Guard.NotNull(configuration, nameof(configuration)); |
||||
|
Guard.DestinationShouldNotBeTooShort(sourcePixels, destinationPixels, nameof(destinationPixels)); |
||||
|
|
||||
|
ref Abgr32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); |
||||
|
ref Rgb48 destRef = ref MemoryMarshal.GetReference(destinationPixels); |
||||
|
|
||||
|
for (nint i = 0; i < sourcePixels.Length; i++) |
||||
|
{ |
||||
|
ref Abgr32 sp = ref Unsafe.Add(ref sourceRef, i); |
||||
|
ref Rgb48 dp = ref Unsafe.Add(ref destRef, i); |
||||
|
|
||||
|
dp.FromAbgr32(sp); |
||||
|
} |
||||
|
} |
||||
|
/// <inheritdoc />
|
||||
|
public override void ToRgba64( |
||||
|
Configuration configuration, |
||||
|
ReadOnlySpan<Abgr32> sourcePixels, |
||||
|
Span<Rgba64> destinationPixels) |
||||
|
{ |
||||
|
Guard.NotNull(configuration, nameof(configuration)); |
||||
|
Guard.DestinationShouldNotBeTooShort(sourcePixels, destinationPixels, nameof(destinationPixels)); |
||||
|
|
||||
|
ref Abgr32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); |
||||
|
ref Rgba64 destRef = ref MemoryMarshal.GetReference(destinationPixels); |
||||
|
|
||||
|
for (nint i = 0; i < sourcePixels.Length; i++) |
||||
|
{ |
||||
|
ref Abgr32 sp = ref Unsafe.Add(ref sourceRef, i); |
||||
|
ref Rgba64 dp = ref Unsafe.Add(ref destRef, i); |
||||
|
|
||||
|
dp.FromAbgr32(sp); |
||||
|
} |
||||
|
} |
||||
|
/// <inheritdoc />
|
||||
|
public override void ToBgra5551( |
||||
|
Configuration configuration, |
||||
|
ReadOnlySpan<Abgr32> sourcePixels, |
||||
|
Span<Bgra5551> destinationPixels) |
||||
|
{ |
||||
|
Guard.NotNull(configuration, nameof(configuration)); |
||||
|
Guard.DestinationShouldNotBeTooShort(sourcePixels, destinationPixels, nameof(destinationPixels)); |
||||
|
|
||||
|
ref Abgr32 sourceRef = ref MemoryMarshal.GetReference(sourcePixels); |
||||
|
ref Bgra5551 destRef = ref MemoryMarshal.GetReference(destinationPixels); |
||||
|
|
||||
|
for (nint i = 0; i < sourcePixels.Length; i++) |
||||
|
{ |
||||
|
ref Abgr32 sp = ref Unsafe.Add(ref sourceRef, i); |
||||
|
ref Bgra5551 dp = ref Unsafe.Add(ref destRef, i); |
||||
|
|
||||
|
dp.FromAbgr32(sp); |
||||
|
} |
||||
|
} |
||||
|
/// <inheritdoc />
|
||||
|
public override void From<TSourcePixel>( |
||||
|
Configuration configuration, |
||||
|
ReadOnlySpan<TSourcePixel> sourcePixels, |
||||
|
Span<Abgr32> destinationPixels) |
||||
|
{ |
||||
|
PixelOperations<TSourcePixel>.Instance.ToAbgr32(configuration, sourcePixels, destinationPixels.Slice(0, sourcePixels.Length)); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
<#@include file="_Common.ttinclude" #> |
||||
|
<#@ output extension=".cs" #> |
||||
|
namespace SixLabors.ImageSharp.PixelFormats |
||||
|
{ |
||||
|
/// <content> |
||||
|
/// Provides optimized overrides for bulk operations. |
||||
|
/// </content> |
||||
|
public partial struct Abgr32 |
||||
|
{ |
||||
|
/// <summary> |
||||
|
/// Provides optimized overrides for bulk operations. |
||||
|
/// </summary> |
||||
|
internal partial class PixelOperations : PixelOperations<Abgr32> |
||||
|
{ |
||||
|
<# GenerateAllDefaultConversionMethods("Abgr32"); #> |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,148 @@ |
|||||
|
// Copyright (c) Six Labors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System.Numerics; |
||||
|
using SixLabors.ImageSharp.PixelFormats; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Tests.PixelFormats |
||||
|
{ |
||||
|
[Trait("Category", "PixelFormats")] |
||||
|
public class Abgr32Tests |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Tests the equality operators for equality.
|
||||
|
/// </summary>
|
||||
|
[Fact] |
||||
|
public void AreEqual() |
||||
|
{ |
||||
|
var color1 = new Abgr32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue); |
||||
|
var color2 = new Abgr32(byte.MaxValue, byte.MaxValue, byte.MaxValue); |
||||
|
|
||||
|
Assert.Equal(color1, color2); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Tests the equality operators for inequality.
|
||||
|
/// </summary>
|
||||
|
[Fact] |
||||
|
public void AreNotEqual() |
||||
|
{ |
||||
|
var color1 = new Abgr32(0, 0, byte.MaxValue, byte.MaxValue); |
||||
|
var color2 = new Abgr32(byte.MaxValue, byte.MaxValue, byte.MaxValue); |
||||
|
|
||||
|
Assert.NotEqual(color1, color2); |
||||
|
} |
||||
|
|
||||
|
public static readonly TheoryData<byte, byte, byte, byte> ColorData = |
||||
|
new() |
||||
|
{ |
||||
|
{ 1, 2, 3, 4 }, |
||||
|
{ 4, 5, 6, 7 }, |
||||
|
{ 0, 255, 42, 0 }, |
||||
|
{ 1, 2, 3, 255 } |
||||
|
}; |
||||
|
|
||||
|
[Theory] |
||||
|
[MemberData(nameof(ColorData))] |
||||
|
public void Constructor(byte b, byte g, byte r, byte a) |
||||
|
{ |
||||
|
var p = new Abgr32(r, g, b, a); |
||||
|
|
||||
|
Assert.Equal(r, p.R); |
||||
|
Assert.Equal(g, p.G); |
||||
|
Assert.Equal(b, p.B); |
||||
|
Assert.Equal(a, p.A); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public unsafe void ByteLayoutIsSequentialBgra() |
||||
|
{ |
||||
|
var color = new Abgr32(1, 2, 3, 4); |
||||
|
byte* ptr = (byte*)&color; |
||||
|
|
||||
|
Assert.Equal(4, ptr[0]); |
||||
|
Assert.Equal(3, ptr[1]); |
||||
|
Assert.Equal(2, ptr[2]); |
||||
|
Assert.Equal(1, ptr[3]); |
||||
|
} |
||||
|
|
||||
|
[Theory] |
||||
|
[MemberData(nameof(ColorData))] |
||||
|
public void Equality_WhenTrue(byte r, byte g, byte b, byte a) |
||||
|
{ |
||||
|
var x = new Abgr32(r, g, b, a); |
||||
|
var y = new Abgr32(r, g, b, a); |
||||
|
|
||||
|
Assert.True(x.Equals(y)); |
||||
|
Assert.True(x.Equals((object)y)); |
||||
|
Assert.Equal(x.GetHashCode(), y.GetHashCode()); |
||||
|
} |
||||
|
|
||||
|
[Theory] |
||||
|
[InlineData(1, 2, 3, 4, 1, 2, 3, 5)] |
||||
|
[InlineData(0, 0, 255, 0, 0, 0, 244, 0)] |
||||
|
[InlineData(0, 255, 0, 0, 0, 244, 0, 0)] |
||||
|
[InlineData(1, 255, 0, 0, 0, 255, 0, 0)] |
||||
|
public void Equality_WhenFalse(byte b1, byte g1, byte r1, byte a1, byte b2, byte g2, byte r2, byte a2) |
||||
|
{ |
||||
|
var x = new Abgr32(r1, g1, b1, a1); |
||||
|
var y = new Abgr32(r2, g2, b2, a2); |
||||
|
|
||||
|
Assert.False(x.Equals(y)); |
||||
|
Assert.False(x.Equals((object)y)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void FromRgba32() |
||||
|
{ |
||||
|
var abgr = default(Abgr32); |
||||
|
abgr.FromRgba32(new Rgba32(1, 2, 3, 4)); |
||||
|
|
||||
|
Assert.Equal(1, abgr.R); |
||||
|
Assert.Equal(2, abgr.G); |
||||
|
Assert.Equal(3, abgr.B); |
||||
|
Assert.Equal(4, abgr.A); |
||||
|
} |
||||
|
|
||||
|
private static Vector4 Vec(byte r, byte g, byte b, byte a = 255) => new Vector4( |
||||
|
r / 255f, |
||||
|
g / 255f, |
||||
|
b / 255f, |
||||
|
a / 255f); |
||||
|
|
||||
|
[Fact] |
||||
|
public void FromVector4() |
||||
|
{ |
||||
|
var c = default(Abgr32); |
||||
|
c.FromVector4(Vec(1, 2, 3, 4)); |
||||
|
|
||||
|
Assert.Equal(1, c.R); |
||||
|
Assert.Equal(2, c.G); |
||||
|
Assert.Equal(3, c.B); |
||||
|
Assert.Equal(4, c.A); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void ToVector4() |
||||
|
{ |
||||
|
var abgr = new Abgr32(1, 2, 3, 4); |
||||
|
|
||||
|
Assert.Equal(Vec(1, 2, 3, 4), abgr.ToVector4()); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Abgr32_FromBgra5551() |
||||
|
{ |
||||
|
// arrange
|
||||
|
var abgr = default(Abgr32); |
||||
|
uint expected = uint.MaxValue; |
||||
|
|
||||
|
// act
|
||||
|
abgr.FromBgra5551(new Bgra5551(1.0f, 1.0f, 1.0f, 1.0f)); |
||||
|
|
||||
|
// assert
|
||||
|
Assert.Equal(expected, abgr.PackedValue); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue