mirror of https://github.com/SixLabors/ImageSharp
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
274 lines
9.6 KiB
274 lines
9.6 KiB
// Copyright (c) Six Labors.
|
|
// Licensed under the Apache License, Version 2.0.
|
|
|
|
using System;
|
|
using System.Globalization;
|
|
using SixLabors.ImageSharp.Processing;
|
|
using Xunit;
|
|
|
|
namespace SixLabors.ImageSharp.Tests.Primitives
|
|
{
|
|
public class ColorMatrixTests
|
|
{
|
|
private readonly ApproximateFloatComparer approximateFloatComparer = new ApproximateFloatComparer(1e-6f);
|
|
|
|
[Fact]
|
|
public void ColorMatrixIdentityIsCorrect()
|
|
{
|
|
ColorMatrix val = default;
|
|
val.M11 = val.M22 = val.M33 = val.M44 = 1F;
|
|
|
|
Assert.Equal(val, ColorMatrix.Identity, this.approximateFloatComparer);
|
|
}
|
|
|
|
[Fact]
|
|
public void ColorMatrixCanDetectIdentity()
|
|
{
|
|
ColorMatrix m = ColorMatrix.Identity;
|
|
Assert.True(m.IsIdentity);
|
|
|
|
m.M12 = 1F;
|
|
Assert.False(m.IsIdentity);
|
|
}
|
|
|
|
[Fact]
|
|
public void ColorMatrixEquality()
|
|
{
|
|
ColorMatrix m = KnownFilterMatrices.CreateHueFilter(45F);
|
|
ColorMatrix m2 = KnownFilterMatrices.CreateHueFilter(45F);
|
|
object obj = m2;
|
|
|
|
Assert.True(m.Equals(obj));
|
|
Assert.True(m.Equals(m2));
|
|
Assert.True(m == m2);
|
|
Assert.False(m != m2);
|
|
}
|
|
|
|
[Fact]
|
|
public void ColorMatrixMultiply()
|
|
{
|
|
ColorMatrix value1 = this.CreateAllTwos();
|
|
ColorMatrix value2 = this.CreateAllThrees();
|
|
|
|
var m = default(ColorMatrix);
|
|
|
|
// First row
|
|
m.M11 = (value1.M11 * value2.M11) + (value1.M12 * value2.M21) + (value1.M13 * value2.M31) + (value1.M14 * value2.M41);
|
|
m.M12 = (value1.M11 * value2.M12) + (value1.M12 * value2.M22) + (value1.M13 * value2.M32) + (value1.M14 * value2.M42);
|
|
m.M13 = (value1.M11 * value2.M13) + (value1.M12 * value2.M23) + (value1.M13 * value2.M33) + (value1.M14 * value2.M43);
|
|
m.M14 = (value1.M11 * value2.M14) + (value1.M12 * value2.M24) + (value1.M13 * value2.M34) + (value1.M14 * value2.M44);
|
|
|
|
// Second row
|
|
m.M21 = (value1.M21 * value2.M11) + (value1.M22 * value2.M21) + (value1.M23 * value2.M31) + (value1.M24 * value2.M41);
|
|
m.M22 = (value1.M21 * value2.M12) + (value1.M22 * value2.M22) + (value1.M23 * value2.M32) + (value1.M24 * value2.M42);
|
|
m.M23 = (value1.M21 * value2.M13) + (value1.M22 * value2.M23) + (value1.M23 * value2.M33) + (value1.M24 * value2.M43);
|
|
m.M24 = (value1.M21 * value2.M14) + (value1.M22 * value2.M24) + (value1.M23 * value2.M34) + (value1.M24 * value2.M44);
|
|
|
|
// Third row
|
|
m.M31 = (value1.M31 * value2.M11) + (value1.M32 * value2.M21) + (value1.M33 * value2.M31) + (value1.M34 * value2.M41);
|
|
m.M32 = (value1.M31 * value2.M12) + (value1.M32 * value2.M22) + (value1.M33 * value2.M32) + (value1.M34 * value2.M42);
|
|
m.M33 = (value1.M31 * value2.M13) + (value1.M32 * value2.M23) + (value1.M33 * value2.M33) + (value1.M34 * value2.M43);
|
|
m.M34 = (value1.M31 * value2.M14) + (value1.M32 * value2.M24) + (value1.M33 * value2.M34) + (value1.M34 * value2.M44);
|
|
|
|
// Fourth row
|
|
m.M41 = (value1.M41 * value2.M11) + (value1.M42 * value2.M21) + (value1.M43 * value2.M31) + (value1.M44 * value2.M41);
|
|
m.M42 = (value1.M41 * value2.M12) + (value1.M42 * value2.M22) + (value1.M43 * value2.M32) + (value1.M44 * value2.M42);
|
|
m.M43 = (value1.M41 * value2.M13) + (value1.M42 * value2.M23) + (value1.M43 * value2.M33) + (value1.M44 * value2.M43);
|
|
m.M44 = (value1.M41 * value2.M14) + (value1.M42 * value2.M24) + (value1.M43 * value2.M34) + (value1.M44 * value2.M44);
|
|
|
|
// Fifth row
|
|
m.M51 = (value1.M51 * value2.M11) + (value1.M52 * value2.M21) + (value1.M53 * value2.M31) + (value1.M54 * value2.M41) + value2.M51;
|
|
m.M52 = (value1.M51 * value2.M12) + (value1.M52 * value2.M22) + (value1.M53 * value2.M32) + (value1.M54 * value2.M52) + value2.M52;
|
|
m.M53 = (value1.M51 * value2.M13) + (value1.M52 * value2.M23) + (value1.M53 * value2.M33) + (value1.M54 * value2.M53) + value2.M53;
|
|
m.M54 = (value1.M51 * value2.M14) + (value1.M52 * value2.M24) + (value1.M53 * value2.M34) + (value1.M54 * value2.M54) + value2.M54;
|
|
|
|
Assert.Equal(m, value1 * value2, this.approximateFloatComparer);
|
|
}
|
|
|
|
[Fact]
|
|
public void ColorMatrixMultiplyScalar()
|
|
{
|
|
ColorMatrix m = this.CreateAllTwos();
|
|
Assert.Equal(this.CreateAllFours(), m * 2, this.approximateFloatComparer);
|
|
}
|
|
|
|
[Fact]
|
|
public void ColorMatrixSubtract()
|
|
{
|
|
ColorMatrix m = this.CreateAllOnes() + this.CreateAllTwos();
|
|
Assert.Equal(this.CreateAllThrees(), m);
|
|
}
|
|
|
|
[Fact]
|
|
public void ColorMatrixNegate()
|
|
{
|
|
ColorMatrix m = this.CreateAllOnes() * -1F;
|
|
Assert.Equal(m, -this.CreateAllOnes());
|
|
}
|
|
|
|
[Fact]
|
|
public void ColorMatrixAdd()
|
|
{
|
|
ColorMatrix m = this.CreateAllOnes() + this.CreateAllTwos();
|
|
Assert.Equal(this.CreateAllThrees(), m);
|
|
}
|
|
|
|
[Fact]
|
|
public void ColorMatrixHashCode()
|
|
{
|
|
#if NETCOREAPP2_1
|
|
ColorMatrix m = KnownFilterMatrices.CreateBrightnessFilter(.5F);
|
|
HashCode hash = default;
|
|
hash.Add(m.M11);
|
|
hash.Add(m.M12);
|
|
hash.Add(m.M13);
|
|
hash.Add(m.M14);
|
|
hash.Add(m.M21);
|
|
hash.Add(m.M22);
|
|
hash.Add(m.M23);
|
|
hash.Add(m.M24);
|
|
hash.Add(m.M31);
|
|
hash.Add(m.M32);
|
|
hash.Add(m.M33);
|
|
hash.Add(m.M34);
|
|
hash.Add(m.M41);
|
|
hash.Add(m.M42);
|
|
hash.Add(m.M43);
|
|
hash.Add(m.M44);
|
|
hash.Add(m.M51);
|
|
hash.Add(m.M52);
|
|
hash.Add(m.M53);
|
|
hash.Add(m.M54);
|
|
|
|
Assert.Equal(hash.ToHashCode(), m.GetHashCode());
|
|
#endif
|
|
}
|
|
|
|
[Fact]
|
|
public void ColorMatrixToString()
|
|
{
|
|
ColorMatrix m = KnownFilterMatrices.CreateBrightnessFilter(.5F);
|
|
|
|
CultureInfo ci = CultureInfo.CurrentCulture;
|
|
|
|
#pragma warning disable SA1117 // Parameters should be on same line or separate lines
|
|
string expected = string.Format(ci, "{{ {{M11:{0} M12:{1} M13:{2} M14:{3}}} {{M21:{4} M22:{5} M23:{6} M24:{7}}} {{M31:{8} M32:{9} M33:{10} M34:{11}}} {{M41:{12} M42:{13} M43:{14} M44:{15}}} {{M51:{16} M52:{17} M53:{18} M54:{19}}} }}",
|
|
m.M11.ToString(ci), m.M12.ToString(ci), m.M13.ToString(ci), m.M14.ToString(ci),
|
|
m.M21.ToString(ci), m.M22.ToString(ci), m.M23.ToString(ci), m.M24.ToString(ci),
|
|
m.M31.ToString(ci), m.M32.ToString(ci), m.M33.ToString(ci), m.M34.ToString(ci),
|
|
m.M41.ToString(ci), m.M42.ToString(ci), m.M43.ToString(ci), m.M44.ToString(ci),
|
|
m.M51.ToString(ci), m.M52.ToString(ci), m.M53.ToString(ci), m.M54.ToString(ci));
|
|
#pragma warning restore SA1117 // Parameters should be on same line or separate lines
|
|
|
|
Assert.Equal(expected, m.ToString());
|
|
}
|
|
|
|
private ColorMatrix CreateAllOnes()
|
|
{
|
|
return new ColorMatrix
|
|
{
|
|
M11 = 1F,
|
|
M12 = 1F,
|
|
M13 = 1F,
|
|
M14 = 1F,
|
|
M21 = 1F,
|
|
M22 = 1F,
|
|
M23 = 1F,
|
|
M24 = 1F,
|
|
M31 = 1F,
|
|
M32 = 1F,
|
|
M33 = 1F,
|
|
M34 = 1F,
|
|
M41 = 1F,
|
|
M42 = 1F,
|
|
M43 = 1F,
|
|
M44 = 1F,
|
|
M51 = 1F,
|
|
M52 = 1F,
|
|
M53 = 1F,
|
|
M54 = 1F
|
|
};
|
|
}
|
|
|
|
private ColorMatrix CreateAllTwos()
|
|
{
|
|
return new ColorMatrix
|
|
{
|
|
M11 = 2F,
|
|
M12 = 2F,
|
|
M13 = 2F,
|
|
M14 = 2F,
|
|
M21 = 2F,
|
|
M22 = 2F,
|
|
M23 = 2F,
|
|
M24 = 2F,
|
|
M31 = 2F,
|
|
M32 = 2F,
|
|
M33 = 2F,
|
|
M34 = 2F,
|
|
M41 = 2F,
|
|
M42 = 2F,
|
|
M43 = 2F,
|
|
M44 = 2F,
|
|
M51 = 2F,
|
|
M52 = 2F,
|
|
M53 = 2F,
|
|
M54 = 2F
|
|
};
|
|
}
|
|
|
|
private ColorMatrix CreateAllThrees()
|
|
{
|
|
return new ColorMatrix
|
|
{
|
|
M11 = 3F,
|
|
M12 = 3F,
|
|
M13 = 3F,
|
|
M14 = 3F,
|
|
M21 = 3F,
|
|
M22 = 3F,
|
|
M23 = 3F,
|
|
M24 = 3F,
|
|
M31 = 3F,
|
|
M32 = 3F,
|
|
M33 = 3F,
|
|
M34 = 3F,
|
|
M41 = 3F,
|
|
M42 = 3F,
|
|
M43 = 3F,
|
|
M44 = 3F,
|
|
M51 = 3F,
|
|
M52 = 3F,
|
|
M53 = 3F,
|
|
M54 = 3F
|
|
};
|
|
}
|
|
|
|
private ColorMatrix CreateAllFours()
|
|
{
|
|
return new ColorMatrix
|
|
{
|
|
M11 = 4F,
|
|
M12 = 4F,
|
|
M13 = 4F,
|
|
M14 = 4F,
|
|
M21 = 4F,
|
|
M22 = 4F,
|
|
M23 = 4F,
|
|
M24 = 4F,
|
|
M31 = 4F,
|
|
M32 = 4F,
|
|
M33 = 4F,
|
|
M34 = 4F,
|
|
M41 = 4F,
|
|
M42 = 4F,
|
|
M43 = 4F,
|
|
M44 = 4F,
|
|
M51 = 4F,
|
|
M52 = 4F,
|
|
M53 = 4F,
|
|
M54 = 4F
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|