@@ -25,7 +25,7 @@ namespace SixLabors.ImageSharp;
2525 /// Initializes a new instance of the <see cref="Color"/> struct.
2626 /// </summary>
2727 /// <param name="vector">The <see cref="Vector4"/> containing the color information.</param>
28- [ MethodImpl ( InliningOptions . ShortMethod ) ]
28+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
2929 private Color ( Vector4 vector )
3030 {
3131 this . data = Numerics . Clamp ( vector , Vector4 . Zero , Vector4 . One ) ;
@@ -36,28 +36,13 @@ private Color(Vector4 vector)
3636 /// Initializes a new instance of the <see cref="Color"/> struct.
3737 /// </summary>
3838 /// <param name="pixel">The pixel containing color information.</param>
39- [ MethodImpl ( InliningOptions . ShortMethod ) ]
39+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
4040 private Color ( IPixel pixel )
4141 {
4242 this . boxedHighPrecisionPixel = pixel ;
4343 this . data = default ;
4444 }
4545
46- /// <summary>
47- /// Converts a <see cref="Color"/> to <see cref="Vector4"/>.
48- /// </summary>
49- /// <param name="color">The <see cref="Color"/>.</param>
50- /// <returns>The <see cref="Vector4"/>.</returns>
51- public static explicit operator Vector4 ( Color color ) => color . ToScaledVector4 ( ) ;
52-
53- /// <summary>
54- /// Converts an <see cref="Vector4"/> to <see cref="Color"/>.
55- /// </summary>
56- /// <param name="source">The <see cref="Vector4"/>.</param>
57- /// <returns>The <see cref="Color"/>.</returns>
58- [ MethodImpl ( InliningOptions . ShortMethod ) ]
59- public static explicit operator Color ( Vector4 source ) => new ( source ) ;
60-
6146 /// <summary>
6247 /// Checks whether two <see cref="Color"/> structures are equal.
6348 /// </summary>
@@ -67,7 +52,7 @@ private Color(IPixel pixel)
6752 /// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter;
6853 /// otherwise, false.
6954 /// </returns>
70- [ MethodImpl ( InliningOptions . ShortMethod ) ]
55+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
7156 public static bool operator == ( Color left , Color right ) => left . Equals ( right ) ;
7257
7358 /// <summary>
@@ -79,36 +64,44 @@ private Color(IPixel pixel)
7964 /// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter;
8065 /// otherwise, false.
8166 /// </returns>
82- [ MethodImpl ( InliningOptions . ShortMethod ) ]
67+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
8368 public static bool operator != ( Color left , Color right ) => ! left . Equals ( right ) ;
8469
8570 /// <summary>
8671 /// Creates a <see cref="Color"/> from the given <typeparamref name="TPixel"/>.
8772 /// </summary>
88- /// <param name="pixel ">The pixel to convert from.</param>
73+ /// <param name="source ">The pixel to convert from.</param>
8974 /// <typeparam name="TPixel">The pixel format.</typeparam>
9075 /// <returns>The <see cref="Color"/>.</returns>
91- [ MethodImpl ( InliningOptions . ShortMethod ) ]
92- public static Color FromPixel < TPixel > ( TPixel pixel )
76+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
77+ public static Color FromPixel < TPixel > ( TPixel source )
9378 where TPixel : unmanaged, IPixel < TPixel >
9479 {
9580 // Avoid boxing in case we can convert to Vector4 safely and efficiently
9681 PixelTypeInfo info = TPixel . GetPixelTypeInfo ( ) ;
9782 if ( info . ComponentInfo . HasValue && info . ComponentInfo . Value . GetMaximumComponentPrecision ( ) <= ( int ) PixelComponentBitDepth . Bit32 )
9883 {
99- return new ( pixel . ToScaledVector4 ( ) ) ;
84+ return new ( source . ToScaledVector4 ( ) ) ;
10085 }
10186
102- return new ( pixel ) ;
87+ return new ( source ) ;
10388 }
10489
90+ /// <summary>
91+ /// Creates a <see cref="Color"/> from a generic scaled <see cref="Vector4"/>.
92+ /// </summary>
93+ /// <param name="source">The vector to load the pixel from.</param>
94+ /// <returns>The <see cref="Color"/>.</returns>
95+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
96+ public static Color FromScaledVector ( Vector4 source ) => new ( source ) ;
97+
10598 /// <summary>
10699 /// Bulk converts a span of a specified <typeparamref name="TPixel"/> type to a span of <see cref="Color"/>.
107100 /// </summary>
108101 /// <typeparam name="TPixel">The pixel type to convert to.</typeparam>
109102 /// <param name="source">The source pixel span.</param>
110103 /// <param name="destination">The destination color span.</param>
111- [ MethodImpl ( InliningOptions . ShortMethod ) ]
104+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
112105 public static void FromPixel < TPixel > ( ReadOnlySpan < TPixel > source , Span < Color > destination )
113106 where TPixel : unmanaged, IPixel < TPixel >
114107 {
@@ -120,7 +113,7 @@ public static void FromPixel<TPixel>(ReadOnlySpan<TPixel> source, Span<Color> de
120113 {
121114 for ( int i = 0 ; i < destination . Length ; i ++ )
122115 {
123- destination [ i ] = new ( source [ i ] . ToScaledVector4 ( ) ) ;
116+ destination [ i ] = FromScaledVector ( source [ i ] . ToScaledVector4 ( ) ) ;
124117 }
125118 }
126119 else
@@ -143,7 +136,7 @@ public static void FromPixel<TPixel>(ReadOnlySpan<TPixel> source, Span<Color> de
143136 /// <returns>
144137 /// The <see cref="Color"/>.
145138 /// </returns>
146- [ MethodImpl ( InliningOptions . ShortMethod ) ]
139+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
147140 public static Color ParseHex ( string hex )
148141 {
149142 Rgba32 rgba = Rgba32 . ParseHex ( hex ) ;
@@ -162,7 +155,7 @@ public static Color ParseHex(string hex)
162155 /// <returns>
163156 /// The <see cref="bool"/>.
164157 /// </returns>
165- [ MethodImpl ( InliningOptions . ShortMethod ) ]
158+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
166159 public static bool TryParseHex ( string hex , out Color result )
167160 {
168161 result = default ;
@@ -236,16 +229,16 @@ public static bool TryParse(string input, out Color result)
236229 /// <returns>The color having it's alpha channel altered.</returns>
237230 public Color WithAlpha ( float alpha )
238231 {
239- Vector4 v = ( Vector4 ) this ;
232+ Vector4 v = this . ToScaledVector4 ( ) ;
240233 v . W = alpha ;
241- return new Color ( v ) ;
234+ return FromScaledVector ( v ) ;
242235 }
243236
244237 /// <summary>
245238 /// Gets the hexadecimal representation of the color instance in rrggbbaa form.
246239 /// </summary>
247240 /// <returns>A hexadecimal string representation of the value.</returns>
248- [ MethodImpl ( InliningOptions . ShortMethod ) ]
241+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
249242 public string ToHex ( )
250243 {
251244 if ( this . boxedHighPrecisionPixel is not null )
@@ -263,8 +256,8 @@ public string ToHex()
263256 /// Converts the color instance to a specified <typeparamref name="TPixel"/> type.
264257 /// </summary>
265258 /// <typeparam name="TPixel">The pixel type to convert to.</typeparam>
266- /// <returns>The pixel value .</returns>
267- [ MethodImpl ( InliningOptions . ShortMethod ) ]
259+ /// <returns>The <typeparamref name="TPixel"/> .</returns>
260+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
268261 public TPixel ToPixel < TPixel > ( )
269262 where TPixel : unmanaged, IPixel < TPixel >
270263 {
@@ -281,13 +274,30 @@ public TPixel ToPixel<TPixel>()
281274 return TPixel . FromScaledVector4 ( this . boxedHighPrecisionPixel . ToScaledVector4 ( ) ) ;
282275 }
283276
277+ /// <summary>
278+ /// Expands the color into a generic ("scaled") <see cref="Vector4"/> representation
279+ /// with values scaled and clamped between <value>0</value> and <value>1</value>.
280+ /// The vector components are typically expanded in least to greatest significance order.
281+ /// </summary>
282+ /// <returns>The <see cref="Vector4"/>.</returns>
283+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
284+ public Vector4 ToScaledVector4 ( )
285+ {
286+ if ( this . boxedHighPrecisionPixel is null )
287+ {
288+ return this . data ;
289+ }
290+
291+ return this . boxedHighPrecisionPixel . ToScaledVector4 ( ) ;
292+ }
293+
284294 /// <summary>
285295 /// Bulk converts a span of <see cref="Color"/> to a span of a specified <typeparamref name="TPixel"/> type.
286296 /// </summary>
287297 /// <typeparam name="TPixel">The pixel type to convert to.</typeparam>
288298 /// <param name="source">The source color span.</param>
289299 /// <param name="destination">The destination pixel span.</param>
290- [ MethodImpl ( InliningOptions . ShortMethod ) ]
300+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
291301 public static void ToPixel < TPixel > ( ReadOnlySpan < Color > source , Span < TPixel > destination )
292302 where TPixel : unmanaged, IPixel < TPixel >
293303 {
@@ -301,7 +311,7 @@ public static void ToPixel<TPixel>(ReadOnlySpan<Color> source, Span<TPixel> dest
301311 }
302312
303313 /// <inheritdoc />
304- [ MethodImpl ( InliningOptions . ShortMethod ) ]
314+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
305315 public bool Equals ( Color other )
306316 {
307317 if ( this . boxedHighPrecisionPixel is null && other . boxedHighPrecisionPixel is null )
@@ -316,7 +326,7 @@ public bool Equals(Color other)
316326 public override bool Equals ( object ? obj ) => obj is Color other && this . Equals ( other ) ;
317327
318328 /// <inheritdoc />
319- [ MethodImpl ( InliningOptions . ShortMethod ) ]
329+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
320330 public override int GetHashCode ( )
321331 {
322332 if ( this . boxedHighPrecisionPixel is null )
@@ -326,15 +336,4 @@ public override int GetHashCode()
326336
327337 return this . boxedHighPrecisionPixel . GetHashCode ( ) ;
328338 }
329-
330- [ MethodImpl ( InliningOptions . ShortMethod ) ]
331- private Vector4 ToScaledVector4 ( )
332- {
333- if ( this . boxedHighPrecisionPixel is null )
334- {
335- return this . data ;
336- }
337-
338- return this . boxedHighPrecisionPixel . ToScaledVector4 ( ) ;
339- }
340339}
0 commit comments