|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Runtime.InteropServices;
namespace System.Drawing.Imaging;
/// <summary>
/// Defines a 5 x 5 matrix that contains the homogeneous coordinates for the RGBA space.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public sealed class ColorMatrix
{
private float _matrix00;
private float _matrix01;
private float _matrix02;
private float _matrix03;
private float _matrix04;
private float _matrix10;
private float _matrix11;
private float _matrix12;
private float _matrix13;
private float _matrix14;
private float _matrix20;
private float _matrix21;
private float _matrix22;
private float _matrix23;
private float _matrix24;
private float _matrix30;
private float _matrix31;
private float _matrix32;
private float _matrix33;
private float _matrix34;
private float _matrix40;
private float _matrix41;
private float _matrix42;
private float _matrix43;
private float _matrix44;
/// <summary>
/// Initializes a new instance of the <see cref='ColorMatrix'/> class.
/// </summary>
public ColorMatrix()
{
// Setup identity matrix by default
_matrix00 = 1.0f;
// matrix01 = 0.0f;
// matrix02 = 0.0f;
// matrix03 = 0.0f;
// matrix04 = 0.0f;
// matrix10 = 0.0f;
_matrix11 = 1.0f;
// matrix12 = 0.0f;
// matrix13 = 0.0f;
// matrix14 = 0.0f;
// matrix20 = 0.0f;
// matrix21 = 0.0f;
_matrix22 = 1.0f;
// matrix23 = 0.0f;
// matrix24 = 0.0f;
// matrix30 = 0.0f;
// matrix31 = 0.0f;
// matrix32 = 0.0f;
_matrix33 = 1.0f;
// matrix34 = 0.0f;
// matrix40 = 0.0f;
// matrix41 = 0.0f;
// matrix42 = 0.0f;
// matrix43 = 0.0f;
_matrix44 = 1.0f;
}
/// <summary>
/// Represents the element at the 0th row and 0th column of this <see cref='ColorMatrix'/>.
/// </summary>
public float Matrix00
{
get => _matrix00;
set => _matrix00 = value;
}
/// <summary>
/// Represents the element at the 0th row and 1st column of this <see cref='ColorMatrix'/>.
/// </summary>
public float Matrix01
{
get => _matrix01;
set => _matrix01 = value;
}
/// <summary>
/// Represents the element at the 0th row and 2nd column of this <see cref='ColorMatrix'/>.
/// </summary>
public float Matrix02
{
get => _matrix02;
set => _matrix02 = value;
}
/// <summary>
/// Represents the element at the 0th row and 3rd column of this <see cref='ColorMatrix'/>.
/// </summary>
public float Matrix03
{
get => _matrix03;
set => _matrix03 = value;
}
/// <summary>
/// Represents the element at the 0th row and 4th column of this <see cref='ColorMatrix'/>.
/// </summary>
public float Matrix04
{
get => _matrix04;
set => _matrix04 = value;
}
/// <summary>
/// Represents the element at the 1st row and 0th column of this <see cref='ColorMatrix'/>.
/// </summary>
public float Matrix10
{
get => _matrix10;
set => _matrix10 = value;
}
/// <summary>
/// Represents the element at the 1st row and 1st column of this <see cref='ColorMatrix'/>.
/// </summary>
public float Matrix11
{
get => _matrix11;
set => _matrix11 = value;
}
/// <summary>
/// Represents the element at the 1st row and 2nd column of this <see cref='ColorMatrix'/>.
/// </summary>
public float Matrix12
{
get => _matrix12;
set => _matrix12 = value;
}
/// <summary>
/// Represents the element at the 1st row and 3rd column of this <see cref='ColorMatrix'/>.
/// </summary>
public float Matrix13
{
get => _matrix13;
set => _matrix13 = value;
}
/// <summary>
/// Represents the element at the 1st row and 4th column of this <see cref='ColorMatrix'/>.
/// </summary>
public float Matrix14
{
get => _matrix14;
set => _matrix14 = value;
}
/// <summary>
/// Represents the element at the 2nd row and 0th column of this <see cref='ColorMatrix'/>.
/// </summary>
public float Matrix20
{
get => _matrix20;
set => _matrix20 = value;
}
/// <summary>
/// Represents the element at the 2nd row and 1st column of this <see cref='ColorMatrix'/>.
/// </summary>
public float Matrix21
{
get => _matrix21;
set => _matrix21 = value;
}
/// <summary>
/// Represents the element at the 2nd row and 2nd column of this <see cref='ColorMatrix'/>.
/// </summary>
public float Matrix22
{
get => _matrix22;
set => _matrix22 = value;
}
/// <summary>
/// Represents the element at the 2nd row and 3rd column of this <see cref='ColorMatrix'/>.
/// </summary>
public float Matrix23
{
get => _matrix23;
set => _matrix23 = value;
}
/// <summary>
/// Represents the element at the 2nd row and 4th column of this <see cref='ColorMatrix'/>.
/// </summary>
public float Matrix24
{
get => _matrix24;
set => _matrix24 = value;
}
/// <summary>
/// Represents the element at the 3rd row and 0th column of this <see cref='ColorMatrix'/>.
/// </summary>
public float Matrix30
{
get => _matrix30;
set => _matrix30 = value;
}
/// <summary>
/// Represents the element at the 3rd row and 1st column of this <see cref='ColorMatrix'/>.
/// </summary>
public float Matrix31
{
get => _matrix31;
set => _matrix31 = value;
}
/// <summary>
/// Represents the element at the 3rd row and 2nd column of this <see cref='ColorMatrix'/>.
/// </summary>
public float Matrix32
{
get => _matrix32;
set => _matrix32 = value;
}
/// <summary>
/// Represents the element at the 3rd row and 3rd column of this <see cref='ColorMatrix'/>.
/// </summary>
public float Matrix33
{
get => _matrix33;
set => _matrix33 = value;
}
/// <summary>
/// Represents the element at the 3rd row and 4th column of this <see cref='ColorMatrix'/>.
/// </summary>
public float Matrix34
{
get => _matrix34;
set => _matrix34 = value;
}
/// <summary>
/// Represents the element at the 4th row and 0th column of this <see cref='ColorMatrix'/>.
/// </summary>
public float Matrix40
{
get => _matrix40;
set => _matrix40 = value;
}
/// <summary>
/// Represents the element at the 4th row and 1st column of this <see cref='ColorMatrix'/>.
/// </summary>
public float Matrix41
{
get => _matrix41;
set => _matrix41 = value;
}
/// <summary>
/// Represents the element at the 4th row and 2nd column of this <see cref='ColorMatrix'/>.
/// </summary>
public float Matrix42
{
get => _matrix42;
set => _matrix42 = value;
}
/// <summary>
/// Represents the element at the 4th row and 3rd column of this <see cref='ColorMatrix'/>.
/// </summary>
public float Matrix43
{
get => _matrix43;
set => _matrix43 = value;
}
/// <summary>
/// Represents the element at the 4th row and 4th column of this <see cref='ColorMatrix'/>.
/// </summary>
public float Matrix44
{
get => _matrix44;
set => _matrix44 = value;
}
/// <summary>
/// Initializes a new instance of the <see cref='ColorMatrix'/> class with the elements in the specified matrix.
/// </summary>
[CLSCompliant(false)]
public ColorMatrix(float[][] newColorMatrix)
{
_matrix00 = newColorMatrix[0][0];
_matrix01 = newColorMatrix[0][1];
_matrix02 = newColorMatrix[0][2];
_matrix03 = newColorMatrix[0][3];
_matrix04 = newColorMatrix[0][4];
_matrix10 = newColorMatrix[1][0];
_matrix11 = newColorMatrix[1][1];
_matrix12 = newColorMatrix[1][2];
_matrix13 = newColorMatrix[1][3];
_matrix14 = newColorMatrix[1][4];
_matrix20 = newColorMatrix[2][0];
_matrix21 = newColorMatrix[2][1];
_matrix22 = newColorMatrix[2][2];
_matrix23 = newColorMatrix[2][3];
_matrix24 = newColorMatrix[2][4];
_matrix30 = newColorMatrix[3][0];
_matrix31 = newColorMatrix[3][1];
_matrix32 = newColorMatrix[3][2];
_matrix33 = newColorMatrix[3][3];
_matrix34 = newColorMatrix[3][4];
_matrix40 = newColorMatrix[4][0];
_matrix41 = newColorMatrix[4][1];
_matrix42 = newColorMatrix[4][2];
_matrix43 = newColorMatrix[4][3];
_matrix44 = newColorMatrix[4][4];
}
#if NET9_0_OR_GREATER
/// <summary>
/// Initializes a new instance of the <see cref='ColorMatrix'/> class with the elements in the specified matrix.
/// </summary>
/// <param name="newColorMatrix">The values of the elements of the new matrix.</param>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="newColorMatrix"/> did not have 25 values.</exception>
public unsafe ColorMatrix(params ReadOnlySpan<float> newColorMatrix)
{
ArgumentOutOfRangeException.ThrowIfNotEqual(newColorMatrix.Length, 25, nameof(newColorMatrix));
fixed (float* f = &_matrix00)
{
newColorMatrix.CopyTo(new Span<float>(f, 25));
}
}
#endif
#pragma warning disable CA2201 // Do not raise reserved exception types - we're manually doing the index check here
/// <summary>
/// Gets or sets the value of the specified element of this <see cref='ColorMatrix'/>.
/// </summary>
public unsafe float this[int row, int column]
{
get
{
if (row is < 0 or > 4)
{
throw new IndexOutOfRangeException(nameof(row));
}
if (column is < 0 or > 4)
{
throw new IndexOutOfRangeException(nameof(column));
}
fixed (float* f = &_matrix00)
{
return f[row * 5 + column];
}
}
set
{
if (row is < 0 or > 4)
{
throw new IndexOutOfRangeException(nameof(row));
}
if (column is < 0 or > 4)
{
throw new IndexOutOfRangeException(nameof(column));
}
fixed (float* f = &_matrix00)
{
f[row * 5 + column] = value;
}
}
}
#pragma warning restore CA2201
internal ref float GetPinnableReference() => ref _matrix00;
}
|