Skip to content

Commit acaebd9

Browse files
Update individual pixel implementations
1 parent c9b4edd commit acaebd9

39 files changed

+1637
-3196
lines changed

src/ImageSharp/Color/Color.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,8 @@ public static Color FromPixel<TPixel>(TPixel pixel)
9898
{
9999
return new(pixel.ToScaledVector4());
100100
}
101-
else
102-
{
103-
return new(pixel);
104-
}
101+
102+
return new(pixel);
105103
}
106104

107105
/// <summary>

src/ImageSharp/Common/Helpers/ColorNumerics.cs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,34 @@ public static int GetBT709Luminance(ref Vector4 vector, int luminanceLevels)
4141
public static byte Get8BitBT709Luminance(byte r, byte g, byte b)
4242
=> (byte)((r * .2126F) + (g * .7152F) + (b * .0722F) + 0.5F);
4343

44+
/// <summary>
45+
/// Gets the luminance from the rgb components using the formula
46+
/// as specified by ITU-R Recommendation BT.709.
47+
/// </summary>
48+
/// <param name="r">The red component.</param>
49+
/// <param name="g">The green component.</param>
50+
/// <param name="b">The blue component.</param>
51+
/// <returns>The <see cref="byte"/>.</returns>
52+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
53+
public static byte Get8BitBT709Luminance(ushort r, ushort g, ushort b)
54+
=> (byte)((From16BitTo8Bit(r) * .2126F) +
55+
(From16BitTo8Bit(g) * .7152F) +
56+
(From16BitTo8Bit(b) * .0722F) + 0.5F);
57+
58+
/// <summary>
59+
/// Gets the luminance from the rgb components using the formula as
60+
/// specified by ITU-R Recommendation BT.709.
61+
/// </summary>
62+
/// <param name="r">The red component.</param>
63+
/// <param name="g">The green component.</param>
64+
/// <param name="b">The blue component.</param>
65+
/// <returns>The <see cref="ushort"/>.</returns>
66+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
67+
public static ushort Get16BitBT709Luminance(byte r, byte g, byte b)
68+
=> (ushort)((From8BitTo16Bit(r) * .2126F) +
69+
(From8BitTo16Bit(g) * .7152F) +
70+
(From8BitTo16Bit(b) * .0722F) + 0.5F);
71+
4472
/// <summary>
4573
/// Gets the luminance from the rgb components using the formula as
4674
/// specified by ITU-R Recommendation BT.709.
@@ -72,8 +100,8 @@ public static ushort Get16BitBT709Luminance(float r, float g, float b)
72100
/// <param name="component">The 8 bit component value.</param>
73101
/// <returns>The <see cref="byte"/></returns>
74102
[MethodImpl(MethodImplOptions.AggressiveInlining)]
75-
public static byte DownScaleFrom16BitTo8Bit(ushort component)
76-
{
103+
public static byte From16BitTo8Bit(ushort component) =>
104+
77105
// To scale to 8 bits From a 16-bit value V the required value (from the PNG specification) is:
78106
//
79107
// (V * 255) / 65535
@@ -102,8 +130,7 @@ public static byte DownScaleFrom16BitTo8Bit(ushort component)
102130
// An alternative arithmetic calculation which also gives no errors is:
103131
//
104132
// (V * 255 + 32895) >> 16
105-
return (byte)(((component * 255) + 32895) >> 16);
106-
}
133+
(byte)(((component * 255) + 32895) >> 16);
107134

108135
/// <summary>
109136
/// Scales a value from an 8 bit <see cref="byte"/> to
@@ -112,7 +139,7 @@ public static byte DownScaleFrom16BitTo8Bit(ushort component)
112139
/// <param name="component">The 8 bit component value.</param>
113140
/// <returns>The <see cref="ushort"/></returns>
114141
[MethodImpl(MethodImplOptions.AggressiveInlining)]
115-
public static ushort UpscaleFrom8BitTo16Bit(byte component)
142+
public static ushort From8BitTo16Bit(byte component)
116143
=> (ushort)(component * 257);
117144

118145
/// <summary>

src/ImageSharp/PixelFormats/IPackedVector{TPacked}.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) Six Labors.
1+
// Copyright (c) Six Labors.
22
// Licensed under the Six Labors Split License.
33

44
namespace SixLabors.ImageSharp.PixelFormats;

src/ImageSharp/PixelFormats/IPixel.cs

Lines changed: 66 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -14,135 +14,151 @@ namespace SixLabors.ImageSharp.PixelFormats;
1414
public interface IPixel<TSelf> : IPixel, IEquatable<TSelf>
1515
where TSelf : unmanaged, IPixel<TSelf>
1616
{
17-
/// <summary>
18-
/// Gets the pixel type information.
19-
/// </summary>
20-
/// <returns>The <see cref="PixelTypeInfo"/>.</returns>
21-
#pragma warning disable CA1000
22-
static abstract PixelTypeInfo GetPixelTypeInfo();
23-
#pragma warning restore CA1000
24-
2517
/// <summary>
2618
/// Creates a <see cref="PixelOperations{TPixel}"/> instance for this pixel type.
2719
/// This method is not intended to be consumed directly. Use <see cref="PixelOperations{TPixel}.Instance"/> instead.
2820
/// </summary>
2921
/// <returns>The <see cref="PixelOperations{TPixel}"/> instance.</returns>
3022
PixelOperations<TSelf> CreatePixelOperations();
31-
}
3223

33-
/// <summary>
34-
/// A base interface for all pixels, defining the mandatory operations to be implemented by a pixel type.
35-
/// </summary>
36-
public interface IPixel
37-
{
38-
/// <summary>
39-
/// Initializes the pixel instance from a generic ("scaled") <see cref="Vector4"/>.
40-
/// </summary>
41-
/// <param name="vector">The vector to load the pixel from.</param>
42-
void FromScaledVector4(Vector4 vector);
24+
#pragma warning disable CA1000 // Do not declare static members on generic types
4325

4426
/// <summary>
45-
/// Expands the pixel into a generic ("scaled") <see cref="Vector4"/> representation
46-
/// with values scaled and clamped between <value>0</value> and <value>1</value>.
47-
/// The vector components are typically expanded in least to greatest significance order.
27+
/// Gets the pixel type information.
4828
/// </summary>
49-
/// <returns>The <see cref="Vector4"/>.</returns>
50-
Vector4 ToScaledVector4();
29+
/// <returns>The <see cref="PixelTypeInfo"/>.</returns>
30+
static abstract PixelTypeInfo GetPixelTypeInfo();
5131

5232
/// <summary>
53-
/// Initializes the pixel instance from a <see cref="Vector4"/> which is specific to the current pixel type.
33+
/// Initializes the pixel instance from a generic scaled <see cref="Vector4"/>.
5434
/// </summary>
55-
/// <param name="vector">The vector to load the pixel from.</param>
56-
void FromVector4(Vector4 vector);
35+
/// <param name="source">The vector to load the pixel from.</param>
36+
/// <returns>The <typeparamref name="TSelf"/>.</returns>
37+
static abstract TSelf FromScaledVector4(Vector4 source);
5738

5839
/// <summary>
59-
/// Expands the pixel into a <see cref="Vector4"/> which is specific to the current pixel type.
60-
/// The vector components are typically expanded in least to greatest significance order.
40+
/// Initializes the pixel instance from a <see cref="Vector4"/> which is specific to the current pixel type.
6141
/// </summary>
62-
/// <returns>The <see cref="Vector4"/>.</returns>
63-
Vector4 ToVector4();
42+
/// <param name="source">The vector to load the pixel from.</param>
43+
/// <returns>The <typeparamref name="TSelf"/>.</returns>
44+
static abstract TSelf FromVector4(Vector4 source);
6445

6546
/// <summary>
6647
/// Initializes the pixel instance from an <see cref="Argb32"/> value.
6748
/// </summary>
6849
/// <param name="source">The <see cref="Argb32"/> value.</param>
69-
void FromArgb32(Argb32 source);
50+
/// <returns>The <typeparamref name="TSelf"/>.</returns>
51+
static virtual TSelf FromArgb32(Argb32 source) => TSelf.FromScaledVector4(source.ToScaledVector4());
7052

7153
/// <summary>
7254
/// Initializes the pixel instance from an <see cref="Bgra5551"/> value.
7355
/// </summary>
7456
/// <param name="source">The <see cref="Bgra5551"/> value.</param>
75-
void FromBgra5551(Bgra5551 source);
57+
/// <returns>The <typeparamref name="TSelf"/>.</returns>
58+
static virtual TSelf FromBgra5551(Bgra5551 source) => TSelf.FromScaledVector4(source.ToScaledVector4());
7659

7760
/// <summary>
7861
/// Initializes the pixel instance from an <see cref="Bgr24"/> value.
7962
/// </summary>
8063
/// <param name="source">The <see cref="Bgr24"/> value.</param>
81-
void FromBgr24(Bgr24 source);
64+
/// <returns>The <typeparamref name="TSelf"/>.</returns>
65+
static virtual TSelf FromBgr24(Bgr24 source) => TSelf.FromScaledVector4(source.ToScaledVector4());
8266

8367
/// <summary>
8468
/// Initializes the pixel instance from an <see cref="Bgra32"/> value.
8569
/// </summary>
8670
/// <param name="source">The <see cref="Bgra32"/> value.</param>
87-
void FromBgra32(Bgra32 source);
71+
/// <returns>The <typeparamref name="TSelf"/>.</returns>
72+
static virtual TSelf FromBgra32(Bgra32 source) => TSelf.FromScaledVector4(source.ToScaledVector4());
8873

8974
/// <summary>
9075
/// Initializes the pixel instance from an <see cref="Abgr32"/> value.
9176
/// </summary>
9277
/// <param name="source">The <see cref="Abgr32"/> value.</param>
93-
void FromAbgr32(Abgr32 source);
78+
/// <returns>The <typeparamref name="TSelf"/>.</returns>
79+
static virtual TSelf FromAbgr32(Abgr32 source) => TSelf.FromScaledVector4(source.ToScaledVector4());
9480

9581
/// <summary>
9682
/// Initializes the pixel instance from an <see cref="L8"/> value.
9783
/// </summary>
9884
/// <param name="source">The <see cref="L8"/> value.</param>
99-
void FromL8(L8 source);
85+
/// <returns>The <typeparamref name="TSelf"/>.</returns>
86+
static virtual TSelf FromL8(L8 source) => TSelf.FromScaledVector4(source.ToScaledVector4());
10087

10188
/// <summary>
10289
/// Initializes the pixel instance from an <see cref="L16"/> value.
10390
/// </summary>
10491
/// <param name="source">The <see cref="L16"/> value.</param>
105-
void FromL16(L16 source);
92+
/// <returns>The <typeparamref name="TSelf"/>.</returns>
93+
static virtual TSelf FromL16(L16 source) => TSelf.FromScaledVector4(source.ToScaledVector4());
10694

10795
/// <summary>
10896
/// Initializes the pixel instance from an <see cref="La16"/> value.
10997
/// </summary>
11098
/// <param name="source">The <see cref="La16"/> value.</param>
111-
void FromLa16(La16 source);
99+
/// <returns>The <typeparamref name="TSelf"/>.</returns>
100+
static virtual TSelf FromLa16(La16 source) => TSelf.FromScaledVector4(source.ToScaledVector4());
112101

113102
/// <summary>
114103
/// Initializes the pixel instance from an <see cref="La32"/> value.
115104
/// </summary>
116105
/// <param name="source">The <see cref="La32"/> value.</param>
117-
void FromLa32(La32 source);
106+
/// <returns>The <typeparamref name="TSelf"/>.</returns>
107+
static virtual TSelf FromLa32(La32 source) => TSelf.FromScaledVector4(source.ToScaledVector4());
118108

119109
/// <summary>
120110
/// Initializes the pixel instance from an <see cref="Rgb24"/> value.
121111
/// </summary>
122112
/// <param name="source">The <see cref="Rgb24"/> value.</param>
123-
void FromRgb24(Rgb24 source);
113+
/// <returns>The <typeparamref name="TSelf"/>.</returns>
114+
static virtual TSelf FromRgb24(Rgb24 source) => TSelf.FromScaledVector4(source.ToScaledVector4());
124115

125116
/// <summary>
126117
/// Initializes the pixel instance from an <see cref="Rgba32"/> value.
127118
/// </summary>
128119
/// <param name="source">The <see cref="Rgba32"/> value.</param>
129-
void FromRgba32(Rgba32 source);
130-
131-
/// <summary>
132-
/// Convert the pixel instance into <see cref="Rgba32"/> representation.
133-
/// </summary>
134-
/// <param name="dest">The reference to the destination <see cref="Rgba32"/> pixel</param>
135-
void ToRgba32(ref Rgba32 dest);
120+
/// <returns>The <typeparamref name="TSelf"/>.</returns>
121+
static virtual TSelf FromRgba32(Rgba32 source) => TSelf.FromScaledVector4(source.ToScaledVector4());
136122

137123
/// <summary>
138124
/// Initializes the pixel instance from an <see cref="Rgb48"/> value.
139125
/// </summary>
140126
/// <param name="source">The <see cref="Rgb48"/> value.</param>
141-
void FromRgb48(Rgb48 source);
127+
/// <returns>The <typeparamref name="TSelf"/>.</returns>
128+
static virtual TSelf FromRgb48(Rgb48 source) => TSelf.FromScaledVector4(source.ToScaledVector4());
142129

143130
/// <summary>
144131
/// Initializes the pixel instance from an <see cref="Rgba64"/> value.
145132
/// </summary>
146133
/// <param name="source">The <see cref="Rgba64"/> value.</param>
147-
void FromRgba64(Rgba64 source);
134+
/// <returns>The <typeparamref name="TSelf"/>.</returns>
135+
static virtual TSelf FromRgba64(Rgba64 source) => TSelf.FromScaledVector4(source.ToScaledVector4());
136+
#pragma warning restore CA1000 // Do not declare static members on generic types
137+
}
138+
139+
/// <summary>
140+
/// A base interface for all pixels, defining the mandatory operations to be implemented by a pixel type.
141+
/// </summary>
142+
public interface IPixel
143+
{
144+
/// <summary>
145+
/// Convert the pixel instance into <see cref="Rgba32"/> representation.
146+
/// </summary>
147+
/// <returns>The <see cref="Rgba32"/></returns>
148+
virtual Rgba32 ToRgba32() => Rgba32.FromScaledVector4(this.ToVector4());
149+
150+
/// <summary>
151+
/// Expands the pixel into a generic ("scaled") <see cref="Vector4"/> representation
152+
/// with values scaled and clamped between <value>0</value> and <value>1</value>.
153+
/// The vector components are typically expanded in least to greatest significance order.
154+
/// </summary>
155+
/// <returns>The <see cref="Vector4"/>.</returns>
156+
Vector4 ToScaledVector4();
157+
158+
/// <summary>
159+
/// Expands the pixel into a <see cref="Vector4"/> which is specific to the current pixel type.
160+
/// The vector components are typically expanded in least to greatest significance order.
161+
/// </summary>
162+
/// <returns>The <see cref="Vector4"/>.</returns>
163+
Vector4 ToVector4();
148164
}

0 commit comments

Comments
 (0)