Skip to content

Commit d2e6f0e

Browse files
committed
Rewrite ColorMatrix
1 parent a2429cc commit d2e6f0e

File tree

2 files changed

+474
-0
lines changed

2 files changed

+474
-0
lines changed
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Six Labors Split License.
3+
4+
#if NET7_0_OR_GREATER
5+
#pragma warning disable SA1117 // Parameters should be on same line or separate lines
6+
using System.Diagnostics.CodeAnalysis;
7+
using System.Numerics;
8+
using System.Runtime.CompilerServices;
9+
10+
namespace SixLabors.ImageSharp;
11+
12+
/// <summary>
13+
/// A structure encapsulating a 5x4 matrix used for transforming the color and alpha components of an image.
14+
/// </summary>
15+
public partial struct ColorMatrix
16+
{
17+
[UnscopedRef]
18+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
19+
internal ref Impl AsImpl() => ref Unsafe.As<ColorMatrix, Impl>(ref this);
20+
21+
[UnscopedRef]
22+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
23+
internal readonly ref readonly Impl AsROImpl() => ref Unsafe.As<ColorMatrix, Impl>(ref Unsafe.AsRef(in this));
24+
25+
internal struct Impl : IEquatable<Impl>
26+
{
27+
public Vector4 X;
28+
public Vector4 Y;
29+
public Vector4 Z;
30+
public Vector4 W;
31+
public Vector4 V;
32+
33+
public static Impl Identity
34+
{
35+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
36+
get
37+
{
38+
Impl result;
39+
40+
result.X = Vector4.UnitX;
41+
result.Y = Vector4.UnitY;
42+
result.Z = Vector4.UnitZ;
43+
result.W = Vector4.UnitW;
44+
result.V = Vector4.Zero;
45+
46+
return result;
47+
}
48+
}
49+
50+
public readonly bool IsIdentity
51+
{
52+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
53+
get =>
54+
(this.X == Vector4.UnitX)
55+
&& (this.Y == Vector4.UnitY)
56+
&& (this.Z == Vector4.UnitZ)
57+
&& (this.W == Vector4.UnitW)
58+
&& (this.V == Vector4.Zero);
59+
}
60+
61+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
62+
public static Impl operator +(in Impl left, in Impl right)
63+
{
64+
Impl result;
65+
66+
result.X = left.X + right.X;
67+
result.Y = left.Y + right.Y;
68+
result.Z = left.Z + right.Z;
69+
result.W = left.W + right.W;
70+
result.V = left.V + right.V;
71+
72+
return result;
73+
}
74+
75+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
76+
public static Impl operator -(in Impl left, in Impl right)
77+
{
78+
Impl result;
79+
80+
result.X = left.X - right.X;
81+
result.Y = left.Y - right.Y;
82+
result.Z = left.Z - right.Z;
83+
result.W = left.W - right.W;
84+
result.V = left.V - right.V;
85+
86+
return result;
87+
}
88+
89+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
90+
public static Impl operator -(in Impl value)
91+
{
92+
Impl result;
93+
94+
result.X = -value.X;
95+
result.Y = -value.Y;
96+
result.Z = -value.Z;
97+
result.W = -value.W;
98+
result.V = -value.V;
99+
100+
return result;
101+
}
102+
103+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
104+
public static Impl operator *(in Impl left, in Impl right)
105+
{
106+
Impl result;
107+
108+
// result.X = Transform(left.X, in right);
109+
result.X = right.X * left.X.X;
110+
result.X += right.Y * left.X.Y;
111+
result.X += right.Z * left.X.Z;
112+
result.X += right.W * left.X.W;
113+
114+
// result.Y = Transform(left.Y, in right);
115+
result.Y = right.X * left.Y.X;
116+
result.Y += right.Y * left.Y.Y;
117+
result.Y += right.Z * left.Y.Z;
118+
result.Y += right.W * left.Y.W;
119+
120+
// result.Z = Transform(left.Z, in right);
121+
result.Z = right.X * left.Z.X;
122+
result.Z += right.Y * left.Z.Y;
123+
result.Z += right.Z * left.Z.Z;
124+
result.Z += right.W * left.Z.W;
125+
126+
// result.W = Transform(left.W, in right);
127+
result.W = right.X * left.W.X;
128+
result.W += right.Y * left.W.Y;
129+
result.W += right.Z * left.W.Z;
130+
result.W += right.W * left.W.W;
131+
132+
// result.V = Transform(left.V, in right);
133+
result.V = right.X * left.V.X;
134+
result.V += right.Y * left.V.Y;
135+
result.V += right.Z * left.V.Z;
136+
result.V += right.W * left.V.W;
137+
138+
return result;
139+
}
140+
141+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
142+
public static Impl operator *(in Impl left, float right)
143+
{
144+
Impl result;
145+
146+
result.X = left.X * right;
147+
result.Y = left.Y * right;
148+
result.Z = left.Z * right;
149+
result.W = left.W * right;
150+
result.V = left.V * right;
151+
152+
return result;
153+
}
154+
155+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
156+
public static bool operator ==(in Impl left, in Impl right) =>
157+
(left.X == right.X)
158+
&& (left.Y == right.Y)
159+
&& (left.Z == right.Z)
160+
&& (left.W == right.W)
161+
&& (left.V == right.V);
162+
163+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
164+
public static bool operator !=(in Impl left, in Impl right) =>
165+
(left.X != right.X)
166+
&& (left.Y != right.Y)
167+
&& (left.Z != right.Z)
168+
&& (left.W != right.W)
169+
&& (left.V != right.V);
170+
171+
[UnscopedRef]
172+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
173+
public ref ColorMatrix AsColorMatrix() => ref Unsafe.As<Impl, ColorMatrix>(ref this);
174+
175+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
176+
public void Init(
177+
float m11, float m12, float m13, float m14,
178+
float m21, float m22, float m23, float m24,
179+
float m31, float m32, float m33, float m34,
180+
float m41, float m42, float m43, float m44,
181+
float m51, float m52, float m53, float m54)
182+
{
183+
this.X = new Vector4(m11, m12, m13, m14);
184+
this.Y = new Vector4(m21, m22, m23, m24);
185+
this.Z = new Vector4(m31, m32, m33, m34);
186+
this.W = new Vector4(m41, m42, m43, m44);
187+
this.V = new Vector4(m51, m52, m53, m54);
188+
}
189+
190+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
191+
public override readonly bool Equals([NotNullWhen(true)] object? obj)
192+
=> (obj is ColorMatrix other) && this.Equals(in other.AsImpl());
193+
194+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
195+
public readonly bool Equals(in Impl other) =>
196+
this.X.Equals(other.X)
197+
&& this.Y.Equals(other.Y)
198+
&& this.Z.Equals(other.Z)
199+
&& this.W.Equals(other.W)
200+
&& this.V.Equals(other.V);
201+
202+
bool IEquatable<Impl>.Equals(Impl other) => this.Equals(in other);
203+
204+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
205+
public override readonly int GetHashCode() => HashCode.Combine(this.X, this.Y, this.Z, this.W, this.V);
206+
}
207+
}
208+
#endif
209+

0 commit comments

Comments
 (0)