1
1
// Copyright (c) Six Labors.
2
2
// Licensed under the Six Labors Split License.
3
3
4
+ using System . Text ;
5
+ using SixLabors . ImageSharp . Formats . Webp ;
4
6
using SixLabors . ImageSharp . Formats . Webp . Lossy ;
5
7
using SixLabors . ImageSharp . Tests . TestUtilities ;
6
8
@@ -9,10 +11,234 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp;
9
11
[ Trait ( "Format" , "Webp" ) ]
10
12
public class Vp8ResidualTests
11
13
{
14
+ private static void WriteVp8Residual ( string filename , Vp8Residual residual )
15
+ {
16
+ using FileStream stream = File . Open ( filename , FileMode . Create ) ;
17
+ using BinaryWriter writer = new ( stream , Encoding . UTF8 , false ) ;
18
+
19
+ writer . Write ( residual . First ) ;
20
+ writer . Write ( residual . Last ) ;
21
+ writer . Write ( residual . CoeffType ) ;
22
+
23
+ for ( int i = 0 ; i < residual . Coeffs . Length ; i ++ )
24
+ {
25
+ writer . Write ( residual . Coeffs [ i ] ) ;
26
+ }
27
+
28
+ for ( int i = 0 ; i < residual . Prob . Length ; i ++ )
29
+ {
30
+ for ( int j = 0 ; j < residual . Prob [ i ] . Probabilities . Length ; j ++ )
31
+ {
32
+ writer . Write ( residual . Prob [ i ] . Probabilities [ j ] . Probabilities ) ;
33
+ }
34
+ }
35
+
36
+ for ( int i = 0 ; i < residual . Costs . Length ; i ++ )
37
+ {
38
+ Vp8Costs costs = residual . Costs [ i ] ;
39
+ Vp8CostArray [ ] costsArray = costs . Costs ;
40
+ for ( int j = 0 ; j < costsArray . Length ; j ++ )
41
+ {
42
+ for ( int k = 0 ; k < costsArray [ j ] . Costs . Length ; k ++ )
43
+ {
44
+ writer . Write ( costsArray [ j ] . Costs [ k ] ) ;
45
+ }
46
+ }
47
+ }
48
+
49
+ for ( int i = 0 ; i < residual . Stats . Length ; i ++ )
50
+ {
51
+ for ( int j = 0 ; j < residual . Stats [ i ] . Stats . Length ; j ++ )
52
+ {
53
+ for ( int k = 0 ; k < residual . Stats [ i ] . Stats [ j ] . Stats . Length ; k ++ )
54
+ {
55
+ writer . Write ( residual . Stats [ i ] . Stats [ j ] . Stats [ k ] ) ;
56
+ }
57
+ }
58
+ }
59
+
60
+ writer . Flush ( ) ;
61
+ }
62
+
63
+ private static Vp8Residual ReadVp8Residual ( string fileName )
64
+ {
65
+ using FileStream stream = File . Open ( fileName , FileMode . Open ) ;
66
+ using BinaryReader reader = new ( stream , Encoding . UTF8 , false ) ;
67
+
68
+ Vp8Residual residual = new ( )
69
+ {
70
+ First = reader . ReadInt32 ( ) ,
71
+ Last = reader . ReadInt32 ( ) ,
72
+ CoeffType = reader . ReadInt32 ( )
73
+ } ;
74
+
75
+ for ( int i = 0 ; i < residual . Coeffs . Length ; i ++ )
76
+ {
77
+ residual . Coeffs [ i ] = reader . ReadInt16 ( ) ;
78
+ }
79
+
80
+ Vp8BandProbas [ ] bandProbas = new Vp8BandProbas [ 8 ] ;
81
+ for ( int i = 0 ; i < bandProbas . Length ; i ++ )
82
+ {
83
+ bandProbas [ i ] = new Vp8BandProbas ( ) ;
84
+ for ( int j = 0 ; j < bandProbas [ i ] . Probabilities . Length ; j ++ )
85
+ {
86
+ for ( int k = 0 ; k < 11 ; k ++ )
87
+ {
88
+ bandProbas [ i ] . Probabilities [ j ] . Probabilities [ k ] = reader . ReadByte ( ) ;
89
+ }
90
+ }
91
+ }
92
+
93
+ residual . Prob = bandProbas ;
94
+
95
+ residual . Costs = new Vp8Costs [ 16 ] ;
96
+ for ( int i = 0 ; i < residual . Costs . Length ; i ++ )
97
+ {
98
+ residual . Costs [ i ] = new Vp8Costs ( ) ;
99
+ Vp8CostArray [ ] costsArray = residual . Costs [ i ] . Costs ;
100
+ for ( int j = 0 ; j < costsArray . Length ; j ++ )
101
+ {
102
+ for ( int k = 0 ; k < costsArray [ j ] . Costs . Length ; k ++ )
103
+ {
104
+ costsArray [ j ] . Costs [ k ] = reader . ReadUInt16 ( ) ;
105
+ }
106
+ }
107
+ }
108
+
109
+ residual . Stats = new Vp8Stats [ 8 ] ;
110
+ for ( int i = 0 ; i < residual . Stats . Length ; i ++ )
111
+ {
112
+ residual . Stats [ i ] = new Vp8Stats ( ) ;
113
+ for ( int j = 0 ; j < residual . Stats [ i ] . Stats . Length ; j ++ )
114
+ {
115
+ for ( int k = 0 ; k < residual . Stats [ i ] . Stats [ j ] . Stats . Length ; k ++ )
116
+ {
117
+ residual . Stats [ i ] . Stats [ j ] . Stats [ k ] = reader . ReadUInt32 ( ) ;
118
+ }
119
+ }
120
+ }
121
+
122
+ return residual ;
123
+ }
124
+
125
+ [ Fact ]
126
+ public void Vp8Residual_Serialization_Works ( )
127
+ {
128
+ // arrange
129
+ Vp8Residual expected = new ( ) ;
130
+ Vp8EncProba encProb = new ( ) ;
131
+ Random rand = new ( 439 ) ;
132
+ CreateRandomProbas ( encProb , rand ) ;
133
+ CreateCosts ( encProb , rand ) ;
134
+ expected . Init ( 1 , 0 , encProb ) ;
135
+ for ( int i = 0 ; i < expected . Coeffs . Length ; i ++ )
136
+ {
137
+ expected . Coeffs [ i ] = ( byte ) rand . Next ( 255 ) ;
138
+ }
139
+
140
+ // act
141
+ string fileName = "Vp8SerializationTest.bin" ;
142
+ WriteVp8Residual ( fileName , expected ) ;
143
+ Vp8Residual actual = ReadVp8Residual ( fileName ) ;
144
+ File . Delete ( fileName ) ;
145
+
146
+ // assert
147
+ Assert . Equal ( expected . CoeffType , actual . CoeffType ) ;
148
+ Assert . Equal ( expected . Coeffs , actual . Coeffs ) ;
149
+ Assert . Equal ( expected . Costs . Length , actual . Costs . Length ) ;
150
+ Assert . Equal ( expected . First , actual . First ) ;
151
+ Assert . Equal ( expected . Last , actual . Last ) ;
152
+ Assert . Equal ( expected . Stats . Length , actual . Stats . Length ) ;
153
+ for ( int i = 0 ; i < expected . Stats . Length ; i ++ )
154
+ {
155
+ Vp8StatsArray [ ] expectedStats = expected . Stats [ i ] . Stats ;
156
+ Vp8StatsArray [ ] actualStats = actual . Stats [ i ] . Stats ;
157
+ Assert . Equal ( expectedStats . Length , actualStats . Length ) ;
158
+ for ( int j = 0 ; j < expectedStats . Length ; j ++ )
159
+ {
160
+ Assert . Equal ( expectedStats [ j ] . Stats , actualStats [ j ] . Stats ) ;
161
+ }
162
+ }
163
+
164
+ Assert . Equal ( expected . Prob . Length , actual . Prob . Length ) ;
165
+ for ( int i = 0 ; i < expected . Prob . Length ; i ++ )
166
+ {
167
+ Vp8ProbaArray [ ] expectedProbabilities = expected . Prob [ i ] . Probabilities ;
168
+ Vp8ProbaArray [ ] actualProbabilities = actual . Prob [ i ] . Probabilities ;
169
+ Assert . Equal ( expectedProbabilities . Length , actualProbabilities . Length ) ;
170
+ for ( int j = 0 ; j < expectedProbabilities . Length ; j ++ )
171
+ {
172
+ Assert . Equal ( expectedProbabilities [ j ] . Probabilities , actualProbabilities [ j ] . Probabilities ) ;
173
+ }
174
+ }
175
+
176
+ for ( int i = 0 ; i < expected . Costs . Length ; i ++ )
177
+ {
178
+ Vp8CostArray [ ] expectedCosts = expected . Costs [ i ] . Costs ;
179
+ Vp8CostArray [ ] actualCosts = actual . Costs [ i ] . Costs ;
180
+ Assert . Equal ( expectedCosts . Length , actualCosts . Length ) ;
181
+ for ( int j = 0 ; j < expectedCosts . Length ; j ++ )
182
+ {
183
+ Assert . Equal ( expectedCosts [ j ] . Costs , actualCosts [ j ] . Costs ) ;
184
+ }
185
+ }
186
+ }
187
+
188
+ [ Fact ]
189
+ public void GetResidualCost_Works ( )
190
+ {
191
+ // arrange
192
+ int ctx0 = 0 ;
193
+ int expected = 20911 ;
194
+ Vp8Residual residual = ReadVp8Residual ( Path . Combine ( "TestDataWebp" , "Vp8Residual.bin" ) ) ;
195
+
196
+ // act
197
+ int actual = residual . GetResidualCost ( ctx0 ) ;
198
+
199
+ // assert
200
+ Assert . Equal ( expected , actual ) ;
201
+ }
202
+
203
+ private static void CreateRandomProbas ( Vp8EncProba probas , Random rand )
204
+ {
205
+ for ( int t = 0 ; t < WebpConstants . NumTypes ; ++ t )
206
+ {
207
+ for ( int b = 0 ; b < WebpConstants . NumBands ; ++ b )
208
+ {
209
+ for ( int c = 0 ; c < WebpConstants . NumCtx ; ++ c )
210
+ {
211
+ for ( int p = 0 ; p < WebpConstants . NumProbas ; ++ p )
212
+ {
213
+ probas . Coeffs [ t ] [ b ] . Probabilities [ c ] . Probabilities [ p ] = ( byte ) rand . Next ( 255 ) ;
214
+ }
215
+ }
216
+ }
217
+ }
218
+ }
219
+
220
+ private static void CreateCosts ( Vp8EncProba probas , Random rand )
221
+ {
222
+ for ( int i = 0 ; i < probas . RemappedCosts . Length ; i ++ )
223
+ {
224
+ for ( int j = 0 ; j < probas . RemappedCosts [ i ] . Length ; j ++ )
225
+ {
226
+ for ( int k = 0 ; k < probas . RemappedCosts [ i ] [ j ] . Costs . Length ; k ++ )
227
+ {
228
+ ushort [ ] costs = probas . RemappedCosts [ i ] [ j ] . Costs [ k ] . Costs ;
229
+ for ( int m = 0 ; m < costs . Length ; m ++ )
230
+ {
231
+ costs [ m ] = ( byte ) rand . Next ( 255 ) ;
232
+ }
233
+ }
234
+ }
235
+ }
236
+ }
237
+
12
238
private static void RunSetCoeffsTest ( )
13
239
{
14
240
// arrange
15
- var residual = new Vp8Residual ( ) ;
241
+ Vp8Residual residual = new ( ) ;
16
242
short [ ] coeffs = { 110 , 0 , - 2 , 0 , 0 , 0 , 0 , 0 , 0 , - 1 , 0 , 0 , 0 , 0 , 0 , 0 } ;
17
243
18
244
// act
@@ -23,11 +249,8 @@ private static void RunSetCoeffsTest()
23
249
}
24
250
25
251
[ Fact ]
26
- public void RunSetCoeffsTest_Works ( ) => RunSetCoeffsTest ( ) ;
27
-
28
- [ Fact ]
29
- public void RunSetCoeffsTest_WithHardwareIntrinsics_Works ( ) => FeatureTestRunner . RunWithHwIntrinsicsFeature ( RunSetCoeffsTest , HwIntrinsics . AllowAll ) ;
252
+ public void SetCoeffsTest_Works ( ) => FeatureTestRunner . RunWithHwIntrinsicsFeature ( RunSetCoeffsTest , HwIntrinsics . AllowAll ) ;
30
253
31
254
[ Fact ]
32
- public void RunSetCoeffsTest_WithoutHardwareIntrinsics_Works ( ) => FeatureTestRunner . RunWithHwIntrinsicsFeature ( RunSetCoeffsTest , HwIntrinsics . DisableHWIntrinsic ) ;
255
+ public void SetCoeffsTest_WithoutSSE2_Works ( ) => FeatureTestRunner . RunWithHwIntrinsicsFeature ( RunSetCoeffsTest , HwIntrinsics . DisableSSE2 ) ;
33
256
}
0 commit comments