@@ -21,7 +21,7 @@ public LookupHuffmanDecoder(
2121 _numBits = 0 ;
2222 }
2323
24- public bool Build ( scoped ReadOnlySpan < byte > codeLengths )
24+ public bool Build ( ReadOnlySpan < byte > codeLengths )
2525 {
2626 if ( codeLengths . Length < _symbolCount )
2727 {
@@ -42,24 +42,27 @@ public bool Build(scoped ReadOnlySpan<byte> codeLengths)
4242
4343 _numBits = maxLength ;
4444
45- if ( _numBits <= 0 || _numBits > 16 )
45+ if ( _numBits > 16 )
4646 {
4747 return false ;
4848 }
4949
50+ if ( _numBits == 0 )
51+ {
52+ return true ;
53+ }
54+
5055 int tableSize = 1 << _numBits ;
5156 if ( _table . Length < tableSize )
5257 {
5358 return false ;
5459 }
5560
5661 var table = _table . Slice ( 0 , tableSize ) ;
57- table . Clear ( ) ;
62+ table . Fill ( ushort . MaxValue ) ;
5863
5964 int position = 0 ;
6065
61- // Mirrors legacy HuffmanTree table construction:
62- // iterate bit length first, then symbol order, filling a flat lookup table.
6366 for ( int bitLength = 1 ; bitLength <= _numBits ; bitLength ++ )
6467 {
6568 for ( ushort symbol = 0 ; symbol < _symbolCount ; symbol ++ )
@@ -78,23 +81,28 @@ public bool Build(scoped ReadOnlySpan<byte> codeLengths)
7881 }
7982 }
8083
81- if ( position != tableSize )
82- {
83- return false ;
84- }
85-
8684 return true ;
8785 }
8886
8987 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
9088 public int Decode ( scoped ref LzxBitReader reader )
9189 {
90+ if ( _numBits == 0 )
91+ {
92+ return - 1 ;
93+ }
94+
9295 if ( ! reader . TryPeekBits ( _numBits , out uint peek ) )
9396 {
9497 return - 1 ;
9598 }
9699
97100 ushort symbol = _table [ ( int ) peek ] ;
101+ if ( symbol == ushort . MaxValue )
102+ {
103+ return - 1 ;
104+ }
105+
98106 int len = _lengths [ symbol ] ;
99107 if ( len <= 0 )
100108 {
0 commit comments