Skip to content

Commit a25a42d

Browse files
committed
Add Etc correctness tests
* Resolves #57
1 parent e9674d1 commit a25a42d

1 file changed

Lines changed: 59 additions & 10 deletions

File tree

AssetRipper.TextureDecoder.Tests/EtcTests.cs

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
using AssetRipper.TextureDecoder.Etc;
2+
using AssetRipper.TextureDecoder.Rgb;
3+
using AssetRipper.TextureDecoder.Rgb.Formats;
24

35
namespace AssetRipper.TextureDecoder.Tests;
46

57
public sealed class EtcTests
68
{
7-
private static DecodingDelegate ETCDelegate { get; } = (data, width, height) => EtcDecoder.DecompressETC(data, width, height, out _);
8-
private static DecodingDelegate ETC2Delegate { get; } = (data, width, height) => EtcDecoder.DecompressETC2(data, width, height, out _);
9-
private static DecodingDelegate ETC2A1Delegate { get; } = (data, width, height) => EtcDecoder.DecompressETC2A1(data, width, height, out _);
10-
private static DecodingDelegate ETC2A8Delegate { get; } = (data, width, height) => EtcDecoder.DecompressETC2A8(data, width, height, out _);
11-
private static DecodingDelegate EACRSignedDelegate { get; } = (data, width, height) => EtcDecoder.DecompressEACRSigned(data, width, height, out _);
12-
private static DecodingDelegate EACRUnsignedDelegate { get; } = (data, width, height) => EtcDecoder.DecompressEACRUnsigned(data, width, height, out _);
13-
private static DecodingDelegate EACRGSignedDelegate { get; } = (data, width, height) => EtcDecoder.DecompressEACRGSigned(data, width, height, out _);
14-
private static DecodingDelegate EACRGUnsignedDelegate { get; } = (data, width, height) => EtcDecoder.DecompressEACRGUnsigned(data, width, height, out _);
9+
private static DecodingDelegate ETCDelegate { get; } = (ArraySegment<byte> data, int width, int height, out byte[] decompressedData) => EtcDecoder.DecompressETC(data, width, height, out decompressedData);
10+
private static DecodingDelegate ETC2Delegate { get; } = (ArraySegment<byte> data, int width, int height, out byte[] decompressedData) => EtcDecoder.DecompressETC2(data, width, height, out decompressedData);
11+
private static DecodingDelegate ETC2A1Delegate { get; } = (ArraySegment<byte> data, int width, int height, out byte[] decompressedData) => EtcDecoder.DecompressETC2A1(data, width, height, out decompressedData);
12+
private static DecodingDelegate ETC2A8Delegate { get; } = (ArraySegment<byte> data, int width, int height, out byte[] decompressedData) => EtcDecoder.DecompressETC2A8(data, width, height, out decompressedData);
13+
private static DecodingDelegate EACRSignedDelegate { get; } = (ArraySegment<byte> data, int width, int height, out byte[] decompressedData) => EtcDecoder.DecompressEACRSigned(data, width, height, out decompressedData);
14+
private static DecodingDelegate EACRUnsignedDelegate { get; } = (ArraySegment<byte> data, int width, int height, out byte[] decompressedData) => EtcDecoder.DecompressEACRUnsigned(data, width, height, out decompressedData);
15+
private static DecodingDelegate EACRGSignedDelegate { get; } = (ArraySegment<byte> data, int width, int height, out byte[] decompressedData) => EtcDecoder.DecompressEACRGSigned(data, width, height, out decompressedData);
16+
private static DecodingDelegate EACRGUnsignedDelegate { get; } = (ArraySegment<byte> data, int width, int height, out byte[] decompressedData) => EtcDecoder.DecompressEACRGUnsigned(data, width, height, out decompressedData);
1517

1618
[Test]
1719
public void DecompressETCTest() => AssertCorrectByteCountReadFor256SquareWithMips(TestFileFolders.EtcTestFiles + "test.etc", ETCDelegate);
@@ -37,17 +39,64 @@ public sealed class EtcTests
3739
[Test]
3840
public void DecompressEACRGUnsignedTest() => AssertCorrectByteCountReadFor256SquareWithMips(TestFileFolders.EtcTestFiles + "test.eac_rg", EACRGUnsignedDelegate);
3941

40-
private delegate int DecodingDelegate(ArraySegment<byte> data, int width, int height);
42+
[Test]
43+
public void CorrectnessETCTest() => AssertCorrectDecompression<AndroidTextures.Logo_12, ColorRGB<byte>>(ETCDelegate, .05, 2.1);
44+
45+
[Test]
46+
public void CorrectnessETC2Test() => AssertCorrectDecompression<AndroidTextures.Logo_11, ColorRGB<byte>>(ETC2Delegate, .15, 1.6);
47+
48+
[Test]
49+
public void CorrectnessETC2A1Test() => AssertCorrectDecompression<AndroidTextures.Logo_08>(ETC2A1Delegate, .15, 1.7);
50+
51+
[Test]
52+
public void CorrectnessETC2A8Test() => AssertCorrectDecompression<AndroidTextures.Logo_07>(ETC2A8Delegate, .15, 1.6);
53+
54+
[Test]
55+
public void CorrectnessEACRUnsignedTest() => AssertCorrectDecompression<AndroidTextures.Logo_16, ColorR<byte>>(EACRUnsignedDelegate, .05, .5);
56+
57+
[Test]
58+
public void CorrectnessEACRGUnsignedTest() => AssertCorrectDecompression<AndroidTextures.Logo_15, ColorRG<byte>>(EACRGUnsignedDelegate, .1, .6);
59+
60+
private delegate int DecodingDelegate(ArraySegment<byte> data, int width, int height, out byte[] decompressedData);
4161

4262
private static void AssertCorrectByteCountReadFor256SquareWithMips(string path, DecodingDelegate decoder)
4363
{
4464
byte[] data = File.ReadAllBytes(path);
4565
int totalBytesRead = 0;
4666
foreach (int size in new int[] { 256, 128, 64, 32, 16, 8, 4, 2, 1 }) //mip maps
4767
{
48-
int bytesRead = decoder.Invoke(new ArraySegment<byte>(data, totalBytesRead, data.Length - totalBytesRead), size, size);
68+
int bytesRead = decoder.Invoke(new ArraySegment<byte>(data, totalBytesRead, data.Length - totalBytesRead), size, size, out _);
4969
totalBytesRead += bytesRead;
5070
}
5171
Assert.That(totalBytesRead, Is.EqualTo(data.Length));
5272
}
73+
74+
private static void AssertCorrectDecompression<T>(DecodingDelegate decoder, double maxMeanDeviation, double maxStandardDeviation) where T : ITexture
75+
{
76+
AssertCorrectDecompression<T, ColorRGBA<byte>>(decoder, maxMeanDeviation, maxStandardDeviation);
77+
}
78+
79+
private static void AssertCorrectDecompression<TTexture, TColor>(DecodingDelegate decoder, double maxMeanDeviation, double maxStandardDeviation) where TTexture : ITexture where TColor : unmanaged, IColor<TColor, byte>
80+
{
81+
byte[] data = TTexture.Data;
82+
int bytesRead = decoder.Invoke(new ArraySegment<byte>(data), TTexture.Width, TTexture.Height, out byte[] decompressedData);
83+
if (!TTexture.Mips)
84+
{
85+
Assert.That(bytesRead, Is.EqualTo(data.Length));
86+
}
87+
88+
byte[] comparisonData = AndroidTextures.Logo_00.Data;
89+
90+
//Remove unused color channels
91+
if (typeof(TColor) != typeof(ColorBGRA32) && typeof(TColor) != typeof(ColorRGBA<byte>))
92+
{
93+
Span<ColorBGRA32> pixels = MemoryMarshal.Cast<byte, ColorBGRA32>((Span<byte>)comparisonData);
94+
for (int i = 0; i < pixels.Length; i++)
95+
{
96+
pixels[i] = pixels[i].Convert<ColorBGRA32, byte, TColor, byte>().Convert<TColor, byte, ColorBGRA32, byte>();
97+
}
98+
}
99+
100+
ByteArrayDeviation.AssertMinimalDeviation(decompressedData, comparisonData, maxMeanDeviation, maxStandardDeviation);
101+
}
53102
}

0 commit comments

Comments
 (0)