// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp.Tests; /// /// Unpacked pixel type containing four 64-bit floating-point values typically ranging from 0 to 1. /// The color components are stored in red, green, blue, and alpha order. /// /// Ranges from [0, 0, 0, 0] to [1, 1, 1, 1] in vector form. /// /// /// /// 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. /// [StructLayout(LayoutKind.Sequential)] public struct RgbaDouble : IPixel { /// /// Gets or sets the red component. /// public double R; /// /// Gets or sets the green component. /// public double G; /// /// Gets or sets the blue component. /// public double B; /// /// Gets or sets the alpha component. /// public double A; private const float MaxBytes = byte.MaxValue; private static readonly Vector4 Max = new(MaxBytes); private static readonly Vector4 Half = new(0.5F); /// /// Initializes a new instance of the struct. /// /// The red component. /// The green component. /// The blue component. /// The alpha component. [MethodImpl(MethodImplOptions.AggressiveInlining)] public RgbaDouble(double r, double g, double b, double a = 1) { this.R = r; this.G = g; this.B = b; this.A = a; } /// /// Compares two objects for equality. /// /// The on the left side of the operand. /// The on the right side of the operand. /// /// True if the parameter is equal to the parameter; otherwise, false. /// [MethodImpl(InliningOptions.ShortMethod)] public static bool operator ==(RgbaDouble left, RgbaDouble right) => left.Equals(right); /// /// Compares two objects for equality. /// /// The on the left side of the operand. /// The on the right side of the operand. /// /// True if the parameter is not equal to the parameter; otherwise, false. /// [MethodImpl(InliningOptions.ShortMethod)] public static bool operator !=(RgbaDouble left, RgbaDouble right) => !left.Equals(right); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly Rgba32 ToRgba32() => Rgba32.FromScaledVector4(this.ToScaledVector4()); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly Vector4 ToScaledVector4() => this.ToVector4(); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly Vector4 ToVector4() => new((float)this.R, (float)this.G, (float)this.B, (float)this.A); /// public static PixelTypeInfo GetPixelTypeInfo() => PixelTypeInfo.Create( PixelComponentInfo.Create(4, 64, 64, 64, 64), PixelColorType.RGB | PixelColorType.Alpha, PixelAlphaRepresentation.Unassociated); /// public static PixelOperations CreatePixelOperations() => new(); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RgbaDouble FromScaledVector4(Vector4 source) => FromVector4(source); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RgbaDouble FromVector4(Vector4 source) { source = Numerics.Clamp(source, Vector4.Zero, Vector4.One); return new RgbaDouble(source.X, source.Y, source.Z, source.W); } /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RgbaDouble FromAbgr32(Abgr32 source) => FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RgbaDouble FromArgb32(Argb32 source) => FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RgbaDouble FromBgra5551(Bgra5551 source) => FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RgbaDouble FromBgr24(Bgr24 source) => FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RgbaDouble FromBgra32(Bgra32 source) => FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RgbaDouble FromL8(L8 source) => FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RgbaDouble FromL16(L16 source) => FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RgbaDouble FromLa16(La16 source) => FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RgbaDouble FromLa32(La32 source) => FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RgbaDouble FromRgb24(Rgb24 source) => FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RgbaDouble FromRgba32(Rgba32 source) => FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RgbaDouble FromRgb48(Rgb48 source) => FromScaledVector4(source.ToScaledVector4()); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static RgbaDouble FromRgba64(Rgba64 source) => FromScaledVector4(source.ToScaledVector4()); /// public override readonly bool Equals(object obj) => obj is RgbaDouble other && this.Equals(other); /// [MethodImpl(InliningOptions.ShortMethod)] public readonly bool Equals(RgbaDouble other) => this.R.Equals(other.R) && this.G.Equals(other.G) && this.B.Equals(other.B) && this.A.Equals(other.A); /// public override readonly string ToString() => FormattableString.Invariant($"RgbaDouble({this.R:#0.##}, {this.G:#0.##}, {this.B:#0.##}, {this.A:#0.##})"); /// public override readonly int GetHashCode() => HashCode.Combine(this.R, this.G, this.B, this.A); }