@ -36,11 +36,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
private const int EofSymbol = 2 5 6 ;
private static readonly short [ ] StaticLCodes ;
private static readonly byte [ ] StaticLLength ;
private static readonly short [ ] StaticDCodes ;
private static readonly byte [ ] StaticDLength ;
private Tree literalTree ;
private Tree distTree ;
private Tree blTree ;
@ -58,49 +53,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
private int extraBits ;
private bool isDisposed ;
// TODO: These should be pre-generated array/readonlyspans.
static DeflaterHuffman ( )
{
// See RFC 1951 3.2.6
// Literal codes
StaticLCodes = new short [ LiteralNumber ] ;
StaticLLength = new byte [ LiteralNumber ] ;
int i = 0 ;
while ( i < 1 4 4 )
{
StaticLCodes [ i ] = BitReverse ( ( 0x030 + i ) < < 8 ) ;
StaticLLength [ i + + ] = 8 ;
}
while ( i < 2 5 6 )
{
StaticLCodes [ i ] = BitReverse ( ( 0x190 - 1 4 4 + i ) < < 7 ) ;
StaticLLength [ i + + ] = 9 ;
}
while ( i < 2 8 0 )
{
StaticLCodes [ i ] = BitReverse ( ( 0x000 - 2 5 6 + i ) < < 9 ) ;
StaticLLength [ i + + ] = 7 ;
}
while ( i < LiteralNumber )
{
StaticLCodes [ i ] = BitReverse ( ( 0x0c0 - 2 8 0 + i ) < < 8 ) ;
StaticLLength [ i + + ] = 8 ;
}
// Distance codes
StaticDCodes = new short [ DistanceNumber ] ;
StaticDLength = new byte [ DistanceNumber ] ;
for ( i = 0 ; i < DistanceNumber ; i + + )
{
StaticDCodes [ i ] = BitReverse ( i < < 1 1 ) ;
StaticDLength [ i ] = 5 ;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="DeflaterHuffman"/> class.
/// </summary>
@ -122,12 +74,80 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
this . pinnedLiteralBuffer = ( short * ) this . literalBufferHandle . Pointer ;
}
#pragma warning disable SA1201 // Elements should appear in the correct order
// See RFC 1951 3.2.6
// Literal codes
private static readonly short [ ] StaticLCodes = new short [ ]
{
1 2 , 1 4 0 , 7 6 , 2 0 4 , 4 4 , 1 7 2 , 1 0 8 , 2 3 6 , 2 8 , 1 5 6 , 9 2 , 2 2 0 , 6 0 , 1 8 8 , 1 2 4 , 2 5 2 ,
2 , 1 3 0 , 6 6 , 1 9 4 , 3 4 , 1 6 2 , 9 8 , 2 2 6 , 1 8 , 1 4 6 , 8 2 , 2 1 0 , 5 0 , 1 7 8 , 1 1 4 , 2 4 2 ,
1 0 , 1 3 8 , 7 4 , 2 0 2 , 4 2 , 1 7 0 , 1 0 6 , 2 3 4 , 2 6 , 1 5 4 , 9 0 , 2 1 8 , 5 8 , 1 8 6 , 1 2 2 , 2 5 0 ,
6 , 1 3 4 , 7 0 , 1 9 8 , 3 8 , 1 6 6 , 1 0 2 , 2 3 0 , 2 2 , 1 5 0 , 8 6 , 2 1 4 , 5 4 , 1 8 2 , 1 1 8 , 2 4 6 ,
1 4 , 1 4 2 , 7 8 , 2 0 6 , 4 6 , 1 7 4 , 1 1 0 , 2 3 8 , 3 0 , 1 5 8 , 9 4 , 2 2 2 , 6 2 , 1 9 0 , 1 2 6 , 2 5 4 ,
1 , 1 2 9 , 6 5 , 1 9 3 , 3 3 , 1 6 1 , 9 7 , 2 2 5 , 1 7 , 1 4 5 , 8 1 , 2 0 9 , 4 9 , 1 7 7 , 1 1 3 , 2 4 1 , 9 ,
1 3 7 , 7 3 , 2 0 1 , 4 1 , 1 6 9 , 1 0 5 , 2 3 3 , 2 5 , 1 5 3 , 8 9 , 2 1 7 , 5 7 , 1 8 5 , 1 2 1 , 2 4 9 , 5 ,
1 3 3 , 6 9 , 1 9 7 , 3 7 , 1 6 5 , 1 0 1 , 2 2 9 , 2 1 , 1 4 9 , 8 5 , 2 1 3 , 5 3 , 1 8 1 , 1 1 7 , 2 4 5 , 1 3 ,
1 4 1 , 7 7 , 2 0 5 , 4 5 , 1 7 3 , 1 0 9 , 2 3 7 , 2 9 , 1 5 7 , 9 3 , 2 2 1 , 6 1 , 1 8 9 , 1 2 5 , 2 5 3 , 1 9 ,
2 7 5 , 1 4 7 , 4 0 3 , 8 3 , 3 3 9 , 2 1 1 , 4 6 7 , 5 1 , 3 0 7 , 1 7 9 , 4 3 5 , 1 1 5 , 3 7 1 , 2 4 3 , 4 9 9 ,
1 1 , 2 6 7 , 1 3 9 , 3 9 5 , 7 5 , 3 3 1 , 2 0 3 , 4 5 9 , 4 3 , 2 9 9 , 1 7 1 , 4 2 7 , 1 0 7 , 3 6 3 , 2 3 5 , 4 9 1 ,
2 7 , 2 8 3 , 1 5 5 , 4 1 1 , 9 1 , 3 4 7 , 2 1 9 , 4 7 5 , 5 9 , 3 1 5 , 1 8 7 , 4 4 3 , 1 2 3 , 3 7 9 , 2 5 1 , 5 0 7 ,
7 , 2 6 3 , 1 3 5 , 3 9 1 , 7 1 , 3 2 7 , 1 9 9 , 4 5 5 , 3 9 , 2 9 5 , 1 6 7 , 4 2 3 , 1 0 3 , 3 5 9 , 2 3 1 , 4 8 7 ,
2 3 , 2 7 9 , 1 5 1 , 4 0 7 , 8 7 , 3 4 3 , 2 1 5 , 4 7 1 , 5 5 , 3 1 1 , 1 8 3 , 4 3 9 , 1 1 9 , 3 7 5 , 2 4 7 , 5 0 3 ,
1 5 , 2 7 1 , 1 4 3 , 3 9 9 , 7 9 , 3 3 5 , 2 0 7 , 4 6 3 , 4 7 , 3 0 3 , 1 7 5 , 4 3 1 , 1 1 1 , 3 6 7 , 2 3 9 , 4 9 5 ,
3 1 , 2 8 7 , 1 5 9 , 4 1 5 , 9 5 , 3 5 1 , 2 2 3 , 4 7 9 , 6 3 , 3 1 9 , 1 9 1 , 4 4 7 , 1 2 7 , 3 8 3 , 2 5 5 , 5 1 1 ,
0 , 6 4 , 3 2 , 9 6 , 1 6 , 8 0 , 4 8 , 1 1 2 , 8 , 7 2 , 4 0 , 1 0 4 , 2 4 , 8 8 , 5 6 , 1 2 0 , 4 , 6 8 , 3 6 ,
1 0 0 , 2 0 , 8 4 , 5 2 , 1 1 6 , 3 , 1 3 1 , 6 7 , 1 9 5 , 3 5 , 1 6 3
} ;
private static ReadOnlySpan < byte > StaticLLength = > new byte [ ]
{
8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 ,
8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 ,
8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 ,
8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 ,
8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 ,
8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 ,
8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 ,
8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 ,
8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 ,
9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 ,
9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 ,
9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 ,
9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 ,
9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 ,
9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 ,
9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 ,
7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 ,
7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 8 , 8 , 8
} ;
// Distance codes and lengths.
private static readonly short [ ] StaticDCodes = new short [ ]
{
0 , 1 6 , 8 , 2 4 , 4 , 2 0 , 1 2 , 2 8 , 2 , 1 8 , 1 0 , 2 6 , 6 , 2 2 , 1 4 ,
3 0 , 1 , 1 7 , 9 , 2 5 , 5 , 2 1 , 1 3 , 2 9 , 3 , 1 9 , 1 1 , 2 7 , 7 , 2 3
} ;
private static ReadOnlySpan < byte > StaticDLength = > new byte [ ]
{
5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 ,
5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5
} ;
#pragma warning restore SA1201 // Elements should appear in the correct order
/// <summary>
/// Gets the lengths of the bit length codes are sent in order of decreasing probability, to avoid transmitting the lengths for unused bit length codes.
/// </summary>
private static ReadOnlySpan < byte > BitLengthOrder = > new byte [ ] { 1 6 , 1 7 , 1 8 , 0 , 8 , 7 , 9 , 6 , 1 0 , 5 , 1 1 , 4 , 1 2 , 3 , 1 3 , 2 , 1 4 , 1 , 1 5 } ;
private static ReadOnlySpan < byte > BitLengthOrder = > new byte [ ]
{
1 6 , 1 7 , 1 8 , 0 , 8 , 7 , 9 , 6 , 1 0 , 5 , 1 1 , 4 , 1 2 , 3 , 1 3 , 2 , 1 4 , 1 , 1 5
} ;
private static ReadOnlySpan < byte > Bit4Reverse = > new byte [ ] { 0 , 8 , 4 , 1 2 , 2 , 1 0 , 6 , 1 4 , 1 , 9 , 5 , 1 3 , 3 , 1 1 , 7 , 1 5 } ;
private static ReadOnlySpan < byte > Bit4Reverse = > new byte [ ]
{
0 , 8 , 4 , 1 2 , 2 , 1 0 , 6 , 1 4 , 1 , 9 , 5 , 1 3 , 3 , 1 1 , 7 , 1 5
} ;
/// <summary>
/// Gets the pending buffer to use.
@ -413,8 +433,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
this . distTree = null ;
this . isDisposed = true ;
}
GC . SuppressFinalize ( this ) ;
}
[MethodImpl(InliningOptions.ShortMethod)]
@ -553,6 +571,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
}
}
[MethodImpl(InliningOptions.HotPath)]
public void BuildTree ( )
{
int numSymbols = this . elementCount ;
@ -964,8 +983,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
this . isDisposed = true ;
}
GC . SuppressFinalize ( this ) ;
}
}
}