11using AssetRipper . TextureDecoder . Etc ;
2+ using AssetRipper . TextureDecoder . Rgb ;
3+ using AssetRipper . TextureDecoder . Rgb . Formats ;
24
35namespace AssetRipper . TextureDecoder . Tests ;
46
57public 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