@@ -25,7 +25,7 @@ namespace SixLabors.ImageSharp;
25
25
/// Initializes a new instance of the <see cref="Color"/> struct.
26
26
/// </summary>
27
27
/// <param name="vector">The <see cref="Vector4"/> containing the color information.</param>
28
- [ MethodImpl ( InliningOptions . ShortMethod ) ]
28
+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
29
29
private Color ( Vector4 vector )
30
30
{
31
31
this . data = Numerics . Clamp ( vector , Vector4 . Zero , Vector4 . One ) ;
@@ -36,28 +36,13 @@ private Color(Vector4 vector)
36
36
/// Initializes a new instance of the <see cref="Color"/> struct.
37
37
/// </summary>
38
38
/// <param name="pixel">The pixel containing color information.</param>
39
- [ MethodImpl ( InliningOptions . ShortMethod ) ]
39
+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
40
40
private Color ( IPixel pixel )
41
41
{
42
42
this . boxedHighPrecisionPixel = pixel ;
43
43
this . data = default ;
44
44
}
45
45
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
-
61
46
/// <summary>
62
47
/// Checks whether two <see cref="Color"/> structures are equal.
63
48
/// </summary>
@@ -67,7 +52,7 @@ private Color(IPixel pixel)
67
52
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter;
68
53
/// otherwise, false.
69
54
/// </returns>
70
- [ MethodImpl ( InliningOptions . ShortMethod ) ]
55
+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
71
56
public static bool operator == ( Color left , Color right ) => left . Equals ( right ) ;
72
57
73
58
/// <summary>
@@ -79,36 +64,44 @@ private Color(IPixel pixel)
79
64
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter;
80
65
/// otherwise, false.
81
66
/// </returns>
82
- [ MethodImpl ( InliningOptions . ShortMethod ) ]
67
+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
83
68
public static bool operator != ( Color left , Color right ) => ! left . Equals ( right ) ;
84
69
85
70
/// <summary>
86
71
/// Creates a <see cref="Color"/> from the given <typeparamref name="TPixel"/>.
87
72
/// </summary>
88
- /// <param name="pixel ">The pixel to convert from.</param>
73
+ /// <param name="source ">The pixel to convert from.</param>
89
74
/// <typeparam name="TPixel">The pixel format.</typeparam>
90
75
/// <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 )
93
78
where TPixel : unmanaged, IPixel < TPixel >
94
79
{
95
80
// Avoid boxing in case we can convert to Vector4 safely and efficiently
96
81
PixelTypeInfo info = TPixel . GetPixelTypeInfo ( ) ;
97
82
if ( info . ComponentInfo . HasValue && info . ComponentInfo . Value . GetMaximumComponentPrecision ( ) <= ( int ) PixelComponentBitDepth . Bit32 )
98
83
{
99
- return new ( pixel . ToScaledVector4 ( ) ) ;
84
+ return new ( source . ToScaledVector4 ( ) ) ;
100
85
}
101
86
102
- return new ( pixel ) ;
87
+ return new ( source ) ;
103
88
}
104
89
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
+
105
98
/// <summary>
106
99
/// Bulk converts a span of a specified <typeparamref name="TPixel"/> type to a span of <see cref="Color"/>.
107
100
/// </summary>
108
101
/// <typeparam name="TPixel">The pixel type to convert to.</typeparam>
109
102
/// <param name="source">The source pixel span.</param>
110
103
/// <param name="destination">The destination color span.</param>
111
- [ MethodImpl ( InliningOptions . ShortMethod ) ]
104
+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
112
105
public static void FromPixel < TPixel > ( ReadOnlySpan < TPixel > source , Span < Color > destination )
113
106
where TPixel : unmanaged, IPixel < TPixel >
114
107
{
@@ -120,7 +113,7 @@ public static void FromPixel<TPixel>(ReadOnlySpan<TPixel> source, Span<Color> de
120
113
{
121
114
for ( int i = 0 ; i < destination . Length ; i ++ )
122
115
{
123
- destination [ i ] = new ( source [ i ] . ToScaledVector4 ( ) ) ;
116
+ destination [ i ] = FromScaledVector ( source [ i ] . ToScaledVector4 ( ) ) ;
124
117
}
125
118
}
126
119
else
@@ -143,7 +136,7 @@ public static void FromPixel<TPixel>(ReadOnlySpan<TPixel> source, Span<Color> de
143
136
/// <returns>
144
137
/// The <see cref="Color"/>.
145
138
/// </returns>
146
- [ MethodImpl ( InliningOptions . ShortMethod ) ]
139
+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
147
140
public static Color ParseHex ( string hex )
148
141
{
149
142
Rgba32 rgba = Rgba32 . ParseHex ( hex ) ;
@@ -162,7 +155,7 @@ public static Color ParseHex(string hex)
162
155
/// <returns>
163
156
/// The <see cref="bool"/>.
164
157
/// </returns>
165
- [ MethodImpl ( InliningOptions . ShortMethod ) ]
158
+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
166
159
public static bool TryParseHex ( string hex , out Color result )
167
160
{
168
161
result = default ;
@@ -236,16 +229,16 @@ public static bool TryParse(string input, out Color result)
236
229
/// <returns>The color having it's alpha channel altered.</returns>
237
230
public Color WithAlpha ( float alpha )
238
231
{
239
- Vector4 v = ( Vector4 ) this ;
232
+ Vector4 v = this . ToScaledVector4 ( ) ;
240
233
v . W = alpha ;
241
- return new Color ( v ) ;
234
+ return FromScaledVector ( v ) ;
242
235
}
243
236
244
237
/// <summary>
245
238
/// Gets the hexadecimal representation of the color instance in rrggbbaa form.
246
239
/// </summary>
247
240
/// <returns>A hexadecimal string representation of the value.</returns>
248
- [ MethodImpl ( InliningOptions . ShortMethod ) ]
241
+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
249
242
public string ToHex ( )
250
243
{
251
244
if ( this . boxedHighPrecisionPixel is not null )
@@ -263,8 +256,8 @@ public string ToHex()
263
256
/// Converts the color instance to a specified <typeparamref name="TPixel"/> type.
264
257
/// </summary>
265
258
/// <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 ) ]
268
261
public TPixel ToPixel < TPixel > ( )
269
262
where TPixel : unmanaged, IPixel < TPixel >
270
263
{
@@ -281,13 +274,30 @@ public TPixel ToPixel<TPixel>()
281
274
return TPixel . FromScaledVector4 ( this . boxedHighPrecisionPixel . ToScaledVector4 ( ) ) ;
282
275
}
283
276
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
+
284
294
/// <summary>
285
295
/// Bulk converts a span of <see cref="Color"/> to a span of a specified <typeparamref name="TPixel"/> type.
286
296
/// </summary>
287
297
/// <typeparam name="TPixel">The pixel type to convert to.</typeparam>
288
298
/// <param name="source">The source color span.</param>
289
299
/// <param name="destination">The destination pixel span.</param>
290
- [ MethodImpl ( InliningOptions . ShortMethod ) ]
300
+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
291
301
public static void ToPixel < TPixel > ( ReadOnlySpan < Color > source , Span < TPixel > destination )
292
302
where TPixel : unmanaged, IPixel < TPixel >
293
303
{
@@ -301,7 +311,7 @@ public static void ToPixel<TPixel>(ReadOnlySpan<Color> source, Span<TPixel> dest
301
311
}
302
312
303
313
/// <inheritdoc />
304
- [ MethodImpl ( InliningOptions . ShortMethod ) ]
314
+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
305
315
public bool Equals ( Color other )
306
316
{
307
317
if ( this . boxedHighPrecisionPixel is null && other . boxedHighPrecisionPixel is null )
@@ -316,7 +326,7 @@ public bool Equals(Color other)
316
326
public override bool Equals ( object ? obj ) => obj is Color other && this . Equals ( other ) ;
317
327
318
328
/// <inheritdoc />
319
- [ MethodImpl ( InliningOptions . ShortMethod ) ]
329
+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
320
330
public override int GetHashCode ( )
321
331
{
322
332
if ( this . boxedHighPrecisionPixel is null )
@@ -326,15 +336,4 @@ public override int GetHashCode()
326
336
327
337
return this . boxedHighPrecisionPixel . GetHashCode ( ) ;
328
338
}
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
- }
340
339
}
0 commit comments