@@ -14,8 +14,6 @@ pub const TINFL_LZ_DICT_SIZE: usize = 32_768;
14
14
/// A struct containing huffman code lengths and the huffman code tree used by the decompressor.
15
15
#[ derive( Clone ) ]
16
16
struct HuffmanTable {
17
- /// Length of the code at each index.
18
- pub code_size : [ u8 ; MAX_HUFF_SYMBOLS_0 ] ,
19
17
/// Fast lookup table for shorter huffman codes.
20
18
///
21
19
/// See `HuffmanTable::fast_lookup`.
@@ -30,7 +28,6 @@ struct HuffmanTable {
30
28
impl HuffmanTable {
31
29
const fn new ( ) -> HuffmanTable {
32
30
HuffmanTable {
33
- code_size : [ 0 ; MAX_HUFF_SYMBOLS_0 ] ,
34
31
look_up : [ 0 ; FAST_LOOKUP_SIZE as usize ] ,
35
32
tree : [ 0 ; MAX_HUFF_TREE_SIZE ] ,
36
33
}
@@ -81,11 +78,10 @@ impl HuffmanTable {
81
78
fn lookup ( & self , bit_buf : BitBuffer ) -> Option < ( i32 , u32 ) > {
82
79
let symbol = self . fast_lookup ( bit_buf) . into ( ) ;
83
80
if symbol >= 0 {
84
- if ( symbol >> 9 ) as u32 != 0 {
85
- Some ( ( symbol, ( symbol >> 9 ) as u32 ) )
86
- } else {
87
- // Zero-length code.
88
- None
81
+ let length = ( symbol >> 9 ) as u32 ;
82
+ match length {
83
+ 0 => None ,
84
+ _ => Some ( ( symbol, length) ) ,
89
85
}
90
86
} else {
91
87
// We didn't get a symbol from the fast lookup table, so check the tree instead.
@@ -101,7 +97,7 @@ const MAX_HUFF_SYMBOLS_0: usize = 288;
101
97
/// The length of the second (distance) huffman table.
102
98
const MAX_HUFF_SYMBOLS_1 : usize = 32 ;
103
99
/// The length of the last (huffman code length) huffman table.
104
- // const _MAX_HUFF_SYMBOLS_2 : usize = 19;
100
+ const MAX_HUFF_SYMBOLS_2 : usize = 19 ;
105
101
/// The maximum length of a code that can be looked up in the fast lookup table.
106
102
const FAST_LOOKUP_BITS : u8 = 10 ;
107
103
/// The size of the fast lookup table.
@@ -167,6 +163,13 @@ type BitBuffer = u64;
167
163
#[ cfg( not( target_pointer_width = "64" ) ) ]
168
164
type BitBuffer = u32 ;
169
165
166
+ /*
167
+ enum HuffmanTableType {
168
+ LiteralLength = 0,
169
+ Dist = 1,
170
+ Huffman = 2,
171
+ }*/
172
+
170
173
/// Main decompression struct.
171
174
///
172
175
#[ derive( Clone ) ]
@@ -182,23 +185,26 @@ pub struct DecompressorOxide {
182
185
/// Adler32 checksum from the zlib header.
183
186
z_adler32 : u32 ,
184
187
/// 1 if the current block is the last block, 0 otherwise.
185
- finish : u32 ,
188
+ finish : u8 ,
186
189
/// The type of the current block.
187
- block_type : u32 ,
190
+ block_type : u8 ,
188
191
/// 1 if the adler32 value should be checked.
189
192
check_adler32 : u32 ,
190
193
/// Last match distance.
191
194
dist : u32 ,
192
195
/// Variable used for match length, symbols, and a number of other things.
193
196
counter : u32 ,
194
197
/// Number of extra bits for the last length or distance code.
195
- num_extra : u32 ,
198
+ num_extra : u8 ,
196
199
/// Number of entries in each huffman table.
197
- table_sizes : [ u32 ; MAX_HUFF_TABLES ] ,
200
+ table_sizes : [ u16 ; MAX_HUFF_TABLES ] ,
198
201
/// Buffer of input data.
199
202
bit_buf : BitBuffer ,
200
203
/// Huffman tables.
201
204
tables : [ HuffmanTable ; MAX_HUFF_TABLES ] ,
205
+ code_size_literal : [ u8 ; MAX_HUFF_SYMBOLS_0 ] ,
206
+ code_size_dist : [ u8 ; MAX_HUFF_SYMBOLS_1 ] ,
207
+ code_size_huffman : [ u8 ; MAX_HUFF_SYMBOLS_2 ] ,
202
208
/// Raw block header.
203
209
raw_header : [ u8 ; 4 ] ,
204
210
/// Huffman length codes.
@@ -245,6 +251,14 @@ impl DecompressorOxide {
245
251
pub ( crate ) const fn zlib_header ( & self ) -> ( u32 , u32 ) {
246
252
( self . z_header0 , self . z_header1 )
247
253
}
254
+
255
+ /*fn code_size_table(&mut self, table_num: u8) -> &mut [u8] {
256
+ match table_num {
257
+ 0 => &mut self.code_size_literal,
258
+ 1 => &mut self.code_size_dist,
259
+ _ => &mut self.code_size_huffman,
260
+ }
261
+ }*/
248
262
}
249
263
250
264
impl Default for DecompressorOxide {
@@ -271,6 +285,9 @@ impl Default for DecompressorOxide {
271
285
HuffmanTable :: new ( ) ,
272
286
HuffmanTable :: new ( ) ,
273
287
] ,
288
+ code_size_literal : [ 0 ; MAX_HUFF_SYMBOLS_0 ] ,
289
+ code_size_dist : [ 0 ; MAX_HUFF_SYMBOLS_1 ] ,
290
+ code_size_huffman : [ 0 ; MAX_HUFF_SYMBOLS_2 ] ,
274
291
raw_header : [ 0 ; 4 ] ,
275
292
len_codes : [ 0 ; MAX_HUFF_SYMBOLS_0 + MAX_HUFF_SYMBOLS_1 + 137 ] ,
276
293
}
@@ -670,11 +687,11 @@ fn undo_bytes(l: &mut LocalVars, max: u32) -> u32 {
670
687
fn start_static_table ( r : & mut DecompressorOxide ) {
671
688
r. table_sizes [ LITLEN_TABLE ] = 288 ;
672
689
r. table_sizes [ DIST_TABLE ] = 32 ;
673
- memset ( & mut r. tables [ LITLEN_TABLE ] . code_size [ 0 ..144 ] , 8 ) ;
674
- memset ( & mut r. tables [ LITLEN_TABLE ] . code_size [ 144 ..256 ] , 9 ) ;
675
- memset ( & mut r. tables [ LITLEN_TABLE ] . code_size [ 256 ..280 ] , 7 ) ;
676
- memset ( & mut r. tables [ LITLEN_TABLE ] . code_size [ 280 ..288 ] , 8 ) ;
677
- memset ( & mut r. tables [ DIST_TABLE ] . code_size [ 0 ..32 ] , 5 ) ;
690
+ memset ( & mut r. code_size_literal [ 0 ..144 ] , 8 ) ;
691
+ memset ( & mut r. code_size_literal [ 144 ..256 ] , 9 ) ;
692
+ memset ( & mut r. code_size_literal [ 256 ..280 ] , 7 ) ;
693
+ memset ( & mut r. code_size_literal [ 280 ..288 ] , 8 ) ;
694
+ memset ( & mut r. code_size_dist [ 0 ..32 ] , 5 ) ;
678
695
}
679
696
680
697
#[ cfg( feature = "rustc-dep-of-std" ) ]
@@ -706,20 +723,25 @@ fn reverse_bits(n: u32) -> u32 {
706
723
fn init_tree ( r : & mut DecompressorOxide , l : & mut LocalVars ) -> Option < Action > {
707
724
loop {
708
725
let bt = r. block_type as usize ;
709
- if bt >= r. tables . len ( ) {
710
- return None ;
711
- }
726
+
727
+ let code_sizes = match bt {
728
+ 0 => & mut r. code_size_literal [ ..] ,
729
+ 1 => & mut r. code_size_dist ,
730
+ 2 => & mut r. code_size_huffman ,
731
+ _ => return None ,
732
+ } ;
712
733
let table = & mut r. tables [ bt] ;
713
- let table_size = r. table_sizes [ bt] as usize ;
714
- if table_size > table. code_size . len ( ) {
715
- return None ;
716
- }
717
- let mut total_symbols = [ 0u32 ; 16 ] ;
734
+
735
+ let mut total_symbols = [ 0u16 ; 16 ] ;
718
736
let mut next_code = [ 0u32 ; 17 ] ;
719
737
memset ( & mut table. look_up [ ..] , 0 ) ;
720
738
memset ( & mut table. tree [ ..] , 0 ) ;
721
739
722
- for & code_size in & table. code_size [ ..table_size] {
740
+ let table_size = r. table_sizes [ bt] as usize ;
741
+ if table_size > code_sizes. len ( ) {
742
+ return None ;
743
+ }
744
+ for & code_size in & code_sizes[ ..table_size] {
723
745
let cs = code_size as usize ;
724
746
if cs >= total_symbols. len ( ) {
725
747
return None ;
@@ -728,15 +750,10 @@ fn init_tree(r: &mut DecompressorOxide, l: &mut LocalVars) -> Option<Action> {
728
750
}
729
751
730
752
let mut used_symbols = 0 ;
731
- let mut total = 0 ;
732
- for ( ts, next) in total_symbols
733
- . iter ( )
734
- . copied ( )
735
- . zip ( next_code. iter_mut ( ) . skip ( 1 ) )
736
- . skip ( 1 )
737
- {
753
+ let mut total = 0u32 ;
754
+ for ( & ts, next) in total_symbols. iter ( ) . zip ( next_code[ 1 ..] . iter_mut ( ) ) . skip ( 1 ) {
738
755
used_symbols += ts;
739
- total += ts ;
756
+ total += u32 :: from ( ts ) ;
740
757
total <<= 1 ;
741
758
* next = total;
742
759
}
@@ -747,7 +764,7 @@ fn init_tree(r: &mut DecompressorOxide, l: &mut LocalVars) -> Option<Action> {
747
764
748
765
let mut tree_next = -1 ;
749
766
for symbol_index in 0 ..table_size {
750
- let code_size = table . code_size [ symbol_index] ;
767
+ let code_size = code_sizes [ symbol_index] ;
751
768
if code_size == 0 || usize:: from ( code_size) >= next_code. len ( ) {
752
769
continue ;
753
770
}
@@ -822,6 +839,7 @@ fn init_tree(r: &mut DecompressorOxide, l: &mut LocalVars) -> Option<Action> {
822
839
}
823
840
824
841
l. counter = 0 ;
842
+
825
843
Some ( Action :: Jump ( DecodeLitlen ) )
826
844
}
827
845
@@ -1203,7 +1221,7 @@ pub fn decompress(
1203
1221
num_bits : r. num_bits ,
1204
1222
dist : r. dist ,
1205
1223
counter : r. counter ,
1206
- num_extra : r. num_extra as u8 ,
1224
+ num_extra : r. num_extra ,
1207
1225
} ;
1208
1226
1209
1227
let mut status = ' state_machine: loop {
@@ -1242,8 +1260,8 @@ pub fn decompress(
1242
1260
// Read the block header and jump to the relevant section depending on the block type.
1243
1261
ReadBlockHeader => generate_state ! ( state, ' state_machine, {
1244
1262
read_bits( & mut l, 3 , & mut in_iter, flags, |l, bits| {
1245
- r. finish = ( bits & 1 ) as u32 ;
1246
- r. block_type = ( bits >> 1 ) as u32 & 3 ;
1263
+ r. finish = ( bits & 1 ) as u8 ;
1264
+ r. block_type = ( ( bits >> 1 ) & 3 ) as u8 ;
1247
1265
match r. block_type {
1248
1266
0 => Action :: Jump ( BlockTypeNoCompression ) ,
1249
1267
1 => {
@@ -1375,12 +1393,12 @@ pub fn decompress(
1375
1393
let num_bits = [ 5 , 5 , 4 ] [ l. counter as usize ] ;
1376
1394
read_bits( & mut l, num_bits, & mut in_iter, flags, |l, bits| {
1377
1395
r. table_sizes[ l. counter as usize ] =
1378
- bits as u32 + u32 :: from ( MIN_TABLE_SIZES [ l. counter as usize ] ) ;
1396
+ bits as u16 + MIN_TABLE_SIZES [ l. counter as usize ] ;
1379
1397
l. counter += 1 ;
1380
1398
Action :: None
1381
1399
} )
1382
1400
} else {
1383
- memset( & mut r. tables [ HUFFLEN_TABLE ] . code_size [ ..] , 0 ) ;
1401
+ memset( & mut r. code_size_huffman [ ..] , 0 ) ;
1384
1402
l. counter = 0 ;
1385
1403
// Check that the litlen and distance are within spec.
1386
1404
// litlen table should be <=286 acc to the RFC and
@@ -1400,25 +1418,24 @@ pub fn decompress(
1400
1418
// Read the 3-bit lengths of the huffman codes describing the huffman code lengths used
1401
1419
// to decode the lengths of the main tables.
1402
1420
ReadHufflenTableCodeSize => generate_state ! ( state, ' state_machine, {
1403
- if l. counter < r. table_sizes[ HUFFLEN_TABLE ] {
1421
+ if l. counter < r. table_sizes[ HUFFLEN_TABLE ] . into ( ) {
1404
1422
read_bits( & mut l, 3 , & mut in_iter, flags, |l, bits| {
1405
1423
// These lengths are not stored in a normal ascending order, but rather one
1406
1424
// specified by the deflate specification intended to put the most used
1407
1425
// values at the front as trailing zero lengths do not have to be stored.
1408
- r. tables[ HUFFLEN_TABLE ]
1409
- . code_size[ HUFFMAN_LENGTH_ORDER [ l. counter as usize ] as usize ] =
1426
+ r. code_size_huffman[ HUFFMAN_LENGTH_ORDER [ l. counter as usize ] as usize ] =
1410
1427
bits as u8 ;
1411
1428
l. counter += 1 ;
1412
1429
Action :: None
1413
1430
} )
1414
1431
} else {
1415
- r. table_sizes[ HUFFLEN_TABLE ] = 19 ;
1432
+ r. table_sizes[ HUFFLEN_TABLE ] = MAX_HUFF_SYMBOLS_2 as u16 ;
1416
1433
init_tree( r, & mut l) . unwrap_or( Action :: End ( TINFLStatus :: Failed ) )
1417
1434
}
1418
1435
} ) ,
1419
1436
1420
1437
ReadLitlenDistTablesCodeSize => generate_state ! ( state, ' state_machine, {
1421
- if l. counter < r. table_sizes[ LITLEN_TABLE ] + r. table_sizes[ DIST_TABLE ] {
1438
+ if l. counter < u32 :: from ( r. table_sizes[ LITLEN_TABLE ] ) + u32 :: from ( r. table_sizes[ DIST_TABLE ] ) {
1422
1439
decode_huffman_code(
1423
1440
r, & mut l, HUFFLEN_TABLE ,
1424
1441
flags, & mut in_iter, |r, l, symbol| {
@@ -1435,16 +1452,16 @@ pub fn decompress(
1435
1452
}
1436
1453
}
1437
1454
)
1438
- } else if l. counter != r. table_sizes[ LITLEN_TABLE ] + r. table_sizes[ DIST_TABLE ] {
1455
+ } else if l. counter != u32 :: from ( r. table_sizes[ LITLEN_TABLE ] ) + u32 :: from ( r. table_sizes[ DIST_TABLE ] ) {
1439
1456
Action :: Jump ( BadCodeSizeSum )
1440
1457
} else {
1441
- r. tables [ LITLEN_TABLE ] . code_size [ ..r. table_sizes[ LITLEN_TABLE ] as usize ]
1458
+ r. code_size_literal [ ..r. table_sizes[ LITLEN_TABLE ] as usize ]
1442
1459
. copy_from_slice( & r. len_codes[ ..r. table_sizes[ LITLEN_TABLE ] as usize ] ) ;
1443
1460
1444
1461
let dist_table_start = r. table_sizes[ LITLEN_TABLE ] as usize ;
1445
1462
let dist_table_end = ( r. table_sizes[ LITLEN_TABLE ] +
1446
1463
r. table_sizes[ DIST_TABLE ] ) as usize ;
1447
- r. tables [ DIST_TABLE ] . code_size [ ..r. table_sizes[ DIST_TABLE ] as usize ]
1464
+ r. code_size_dist [ ..r. table_sizes[ DIST_TABLE ] as usize ]
1448
1465
. copy_from_slice( & r. len_codes[ dist_table_start..dist_table_end] ) ;
1449
1466
1450
1467
r. block_type -= 1 ;
@@ -1782,7 +1799,7 @@ pub fn decompress(
1782
1799
r. num_bits = l. num_bits ;
1783
1800
r. dist = l. dist ;
1784
1801
r. counter = l. counter ;
1785
- r. num_extra = l. num_extra . into ( ) ;
1802
+ r. num_extra = l. num_extra ;
1786
1803
1787
1804
r. bit_buf &= ( ( 1 as BitBuffer ) << r. num_bits ) - 1 ;
1788
1805
@@ -1908,7 +1925,7 @@ mod test {
1908
1925
num_bits : d. num_bits ,
1909
1926
dist : d. dist ,
1910
1927
counter : d. counter ,
1911
- num_extra : d. num_extra as u8 ,
1928
+ num_extra : d. num_extra ,
1912
1929
} ;
1913
1930
init_tree ( & mut d, & mut l) . unwrap ( ) ;
1914
1931
let llt = & d. tables [ LITLEN_TABLE ] ;
0 commit comments