1
1
// Copyright (c) Six Labors.
2
2
// Licensed under the Six Labors Split License.
3
- #nullable disable
4
3
5
4
using System . Buffers ;
5
+ using System . Diagnostics . CodeAnalysis ;
6
6
using System . Runtime . CompilerServices ;
7
7
using System . Runtime . InteropServices ;
8
8
using System . Runtime . Intrinsics ;
@@ -38,7 +38,7 @@ public AlphaDecoder(int width, int height, IMemoryOwner<byte> data, byte alphaCh
38
38
this . LastRow = 0 ;
39
39
int totalPixels = width * height ;
40
40
41
- var compression = ( WebpAlphaCompressionMethod ) ( alphaChunkHeader & 0x03 ) ;
41
+ WebpAlphaCompressionMethod compression = ( WebpAlphaCompressionMethod ) ( alphaChunkHeader & 0x03 ) ;
42
42
if ( compression is not WebpAlphaCompressionMethod . NoCompression and not WebpAlphaCompressionMethod . WebpLosslessCompression )
43
43
{
44
44
WebpThrowHelper . ThrowImageFormatException ( $ "unexpected alpha compression method { compression } found") ;
@@ -59,7 +59,7 @@ public AlphaDecoder(int width, int height, IMemoryOwner<byte> data, byte alphaCh
59
59
60
60
if ( this . Compressed )
61
61
{
62
- var bitReader = new Vp8LBitReader ( data ) ;
62
+ Vp8LBitReader bitReader = new ( data ) ;
63
63
this . LosslessDecoder = new WebpLosslessDecoder ( bitReader , memoryAllocator , configuration ) ;
64
64
this . LosslessDecoder . DecodeImageStream ( this . Vp8LDec , width , height , true ) ;
65
65
@@ -110,6 +110,7 @@ public AlphaDecoder(int width, int height, IMemoryOwner<byte> data, byte alphaCh
110
110
/// <summary>
111
111
/// Gets a value indicating whether the alpha channel uses compression.
112
112
/// </summary>
113
+ [ MemberNotNullWhen ( true , nameof ( LosslessDecoder ) ) ]
113
114
private bool Compressed { get ; }
114
115
115
116
/// <summary>
@@ -120,7 +121,7 @@ public AlphaDecoder(int width, int height, IMemoryOwner<byte> data, byte alphaCh
120
121
/// <summary>
121
122
/// Gets the Vp8L decoder which is used to de compress the alpha channel, if needed.
122
123
/// </summary>
123
- private WebpLosslessDecoder LosslessDecoder { get ; }
124
+ private WebpLosslessDecoder ? LosslessDecoder { get ; }
124
125
125
126
/// <summary>
126
127
/// Gets a value indicating whether the decoding needs 1 byte per pixel for decoding.
@@ -173,17 +174,14 @@ public void Decode()
173
174
dst = dst [ this . Width ..] ;
174
175
}
175
176
}
177
+ else if ( this . Use8BDecode )
178
+ {
179
+ this . LosslessDecoder . DecodeAlphaData ( this ) ;
180
+ }
176
181
else
177
182
{
178
- if ( this . Use8BDecode )
179
- {
180
- this . LosslessDecoder . DecodeAlphaData ( this ) ;
181
- }
182
- else
183
- {
184
- this . LosslessDecoder . DecodeImageData ( this . Vp8LDec , this . Vp8LDec . Pixels . Memory . Span ) ;
185
- this . ExtractAlphaRows ( this . Vp8LDec ) ;
186
- }
183
+ this . LosslessDecoder . DecodeImageData ( this . Vp8LDec , this . Vp8LDec . Pixels . Memory . Span ) ;
184
+ this . ExtractAlphaRows ( this . Vp8LDec ) ;
187
185
}
188
186
}
189
187
@@ -261,8 +259,7 @@ private void ExtractAlphaRows(Vp8LDecoder dec)
261
259
{
262
260
int numRowsToProcess = dec . Height ;
263
261
int width = dec . Width ;
264
- Span < uint > pixels = dec . Pixels . Memory . Span ;
265
- Span < uint > input = pixels ;
262
+ Span < uint > input = dec . Pixels . Memory . Span ;
266
263
Span < byte > output = this . Alpha . Memory . Span ;
267
264
268
265
// Extract alpha (which is stored in the green plane).
@@ -327,7 +324,7 @@ private static void HorizontalUnfilter(Span<byte> prev, Span<byte> input, Span<b
327
324
ref byte srcRef = ref MemoryMarshal . GetReference ( input ) ;
328
325
for ( i = 1 ; i + 8 <= width ; i += 8 )
329
326
{
330
- var a0 = Vector128 . Create ( Unsafe . As < byte , long > ( ref Unsafe . Add ( ref srcRef , i ) ) , 0 ) ;
327
+ Vector128 < long > a0 = Vector128 . Create ( Unsafe . As < byte , long > ( ref Unsafe . Add ( ref srcRef , i ) ) , 0 ) ;
331
328
Vector128 < byte > a1 = Sse2 . Add ( a0 . AsByte ( ) , last . AsByte ( ) ) ;
332
329
Vector128 < byte > a2 = Sse2 . ShiftLeftLogical128BitLane ( a1 , 1 ) ;
333
330
Vector128 < byte > a3 = Sse2 . Add ( a1 , a2 ) ;
@@ -365,32 +362,29 @@ private static void VerticalUnfilter(Span<byte> prev, Span<byte> input, Span<byt
365
362
{
366
363
HorizontalUnfilter ( null , input , dst , width ) ;
367
364
}
368
- else
365
+ else if ( Avx2 . IsSupported )
369
366
{
370
- if ( Avx2 . IsSupported )
367
+ nint i ;
368
+ int maxPos = width & ~ 31 ;
369
+ for ( i = 0 ; i < maxPos ; i += 32 )
371
370
{
372
- nint i ;
373
- int maxPos = width & ~ 31 ;
374
- for ( i = 0 ; i < maxPos ; i += 32 )
375
- {
376
- Vector256 < int > a0 = Unsafe . As < byte , Vector256 < int > > ( ref Unsafe . Add ( ref MemoryMarshal . GetReference ( input ) , i ) ) ;
377
- Vector256 < int > b0 = Unsafe . As < byte , Vector256 < int > > ( ref Unsafe . Add ( ref MemoryMarshal . GetReference ( prev ) , i ) ) ;
378
- Vector256 < byte > c0 = Avx2 . Add ( a0 . AsByte ( ) , b0 . AsByte ( ) ) ;
379
- ref byte outputRef = ref Unsafe . Add ( ref MemoryMarshal . GetReference ( dst ) , i ) ;
380
- Unsafe . As < byte , Vector256 < byte > > ( ref outputRef ) = c0;
381
- }
371
+ Vector256 < int > a0 = Unsafe . As < byte , Vector256 < int > > ( ref Unsafe . Add ( ref MemoryMarshal . GetReference ( input ) , i ) ) ;
372
+ Vector256 < int > b0 = Unsafe . As < byte , Vector256 < int > > ( ref Unsafe . Add ( ref MemoryMarshal . GetReference ( prev ) , i ) ) ;
373
+ Vector256 < byte > c0 = Avx2 . Add ( a0 . AsByte ( ) , b0 . AsByte ( ) ) ;
374
+ ref byte outputRef = ref Unsafe . Add ( ref MemoryMarshal . GetReference ( dst ) , i ) ;
375
+ Unsafe . As < byte , Vector256 < byte > > ( ref outputRef ) = c0;
376
+ }
382
377
383
- for ( ; i < width ; i ++ )
384
- {
385
- dst [ ( int ) i ] = ( byte ) ( prev [ ( int ) i ] + input [ ( int ) i ] ) ;
386
- }
378
+ for ( ; i < width ; i ++ )
379
+ {
380
+ dst [ ( int ) i ] = ( byte ) ( prev [ ( int ) i ] + input [ ( int ) i ] ) ;
387
381
}
388
- else
382
+ }
383
+ else
384
+ {
385
+ for ( int i = 0 ; i < width ; i ++ )
389
386
{
390
- for ( int i = 0 ; i < width ; i ++ )
391
- {
392
- dst [ i ] = ( byte ) ( prev [ i ] + input [ i ] ) ;
393
- }
387
+ dst [ i ] = ( byte ) ( prev [ i ] + input [ i ] ) ;
394
388
}
395
389
}
396
390
}
0 commit comments