1
1
use crate :: decode:: lzbuffer:: { LzBuffer , LzCircularBuffer } ;
2
- use crate :: decode:: rangecoder;
3
- use crate :: decode:: rangecoder:: RangeDecoder ;
4
- use crate :: decompress:: Options ;
5
- use crate :: decompress:: UnpackedSize ;
2
+ use crate :: decode:: rangecoder:: { BitTree , LenDecoder , RangeDecoder } ;
3
+ use crate :: decompress:: { Options , UnpackedSize } ;
6
4
use crate :: error;
5
+ use crate :: util:: vec2d:: Vec2D ;
7
6
use byteorder:: { LittleEndian , ReadBytesExt } ;
8
7
use std:: io;
9
8
@@ -167,9 +166,9 @@ pub(crate) struct DecoderState {
167
166
partial_input_buf : std:: io:: Cursor < [ u8 ; MAX_REQUIRED_INPUT ] > ,
168
167
pub ( crate ) lzma_props : LzmaProperties ,
169
168
unpacked_size : Option < u64 > ,
170
- literal_probs : Vec < Vec < u16 > > ,
171
- pos_slot_decoder : Vec < rangecoder :: BitTree > ,
172
- align_decoder : rangecoder :: BitTree ,
169
+ literal_probs : Vec2D < u16 > ,
170
+ pos_slot_decoder : [ BitTree ; 4 ] ,
171
+ align_decoder : BitTree ,
173
172
pos_decoders : [ u16 ; 115 ] ,
174
173
is_match : [ u16 ; 192 ] , // true = LZ, false = literal
175
174
is_rep : [ u16 ; 12 ] ,
@@ -179,8 +178,8 @@ pub(crate) struct DecoderState {
179
178
is_rep_0long : [ u16 ; 192 ] ,
180
179
state : usize ,
181
180
rep : [ usize ; 4 ] ,
182
- len_decoder : rangecoder :: LenDecoder ,
183
- rep_len_decoder : rangecoder :: LenDecoder ,
181
+ len_decoder : LenDecoder ,
182
+ rep_len_decoder : LenDecoder ,
184
183
}
185
184
186
185
impl DecoderState {
@@ -190,9 +189,14 @@ impl DecoderState {
190
189
partial_input_buf : std:: io:: Cursor :: new ( [ 0 ; MAX_REQUIRED_INPUT ] ) ,
191
190
lzma_props,
192
191
unpacked_size,
193
- literal_probs : vec ! [ vec![ 0x400 ; 0x300 ] ; 1 << ( lzma_props. lc + lzma_props. lp) ] ,
194
- pos_slot_decoder : vec ! [ rangecoder:: BitTree :: new( 6 ) ; 4 ] ,
195
- align_decoder : rangecoder:: BitTree :: new ( 4 ) ,
192
+ literal_probs : Vec2D :: init ( 0x400 , ( 1 << ( lzma_props. lc + lzma_props. lp ) , 0x300 ) ) ,
193
+ pos_slot_decoder : [
194
+ BitTree :: new ( 6 ) ,
195
+ BitTree :: new ( 6 ) ,
196
+ BitTree :: new ( 6 ) ,
197
+ BitTree :: new ( 6 ) ,
198
+ ] ,
199
+ align_decoder : BitTree :: new ( 4 ) ,
196
200
pos_decoders : [ 0x400 ; 115 ] ,
197
201
is_match : [ 0x400 ; 192 ] ,
198
202
is_rep : [ 0x400 ; 12 ] ,
@@ -202,33 +206,36 @@ impl DecoderState {
202
206
is_rep_0long : [ 0x400 ; 192 ] ,
203
207
state : 0 ,
204
208
rep : [ 0 ; 4 ] ,
205
- len_decoder : rangecoder :: LenDecoder :: new ( ) ,
206
- rep_len_decoder : rangecoder :: LenDecoder :: new ( ) ,
209
+ len_decoder : LenDecoder :: new ( ) ,
210
+ rep_len_decoder : LenDecoder :: new ( ) ,
207
211
}
208
212
}
209
213
210
214
pub fn reset_state ( & mut self , new_props : LzmaProperties ) {
211
215
new_props. validate ( ) ;
212
216
if self . lzma_props . lc + self . lzma_props . lp == new_props. lc + new_props. lp {
213
217
// We can reset here by filling the existing buffer with 0x400.
214
- self . literal_probs . iter_mut ( ) . for_each ( |v| v . fill ( 0x400 ) )
218
+ self . literal_probs . fill ( 0x400 ) ;
215
219
} else {
216
220
// We need to reallocate because of the new size of `lc+lp`.
217
- self . literal_probs = vec ! [ vec! [ 0x400 ; 0x300 ] ; 1 << ( new_props. lc + new_props. lp) ] ;
221
+ self . literal_probs = Vec2D :: init ( 0x400 , ( 1 << ( new_props. lc + new_props. lp ) , 0x300 ) ) ;
218
222
}
219
223
220
224
self . lzma_props = new_props;
221
225
self . pos_slot_decoder . iter_mut ( ) . for_each ( |t| t. reset ( ) ) ;
222
226
self . align_decoder . reset ( ) ;
223
- self . pos_decoders . fill ( 0x400 ) ;
224
- self . is_match . fill ( 0x400 ) ;
225
- self . is_rep . fill ( 0x400 ) ;
226
- self . is_rep_g0 . fill ( 0x400 ) ;
227
- self . is_rep_g1 . fill ( 0x400 ) ;
228
- self . is_rep_g2 . fill ( 0x400 ) ;
229
- self . is_rep_0long . fill ( 0x400 ) ;
227
+ // For stack-allocated arrays, it was found to be faster to re-create new arrays
228
+ // dropping the existing one, rather than using `fill` to reset the contents to zero.
229
+ // Heap-based arrays use fill to keep their allocation rather than reallocate.
230
+ self . pos_decoders = [ 0x400 ; 115 ] ;
231
+ self . is_match = [ 0x400 ; 192 ] ;
232
+ self . is_rep = [ 0x400 ; 12 ] ;
233
+ self . is_rep_g0 = [ 0x400 ; 12 ] ;
234
+ self . is_rep_g1 = [ 0x400 ; 12 ] ;
235
+ self . is_rep_g2 = [ 0x400 ; 12 ] ;
236
+ self . is_rep_0long = [ 0x400 ; 192 ] ;
230
237
self . state = 0 ;
231
- self . rep . fill ( 0 ) ;
238
+ self . rep = [ 0 ; 4 ] ;
232
239
self . len_decoder . reset ( ) ;
233
240
self . rep_len_decoder . reset ( ) ;
234
241
}
@@ -240,7 +247,7 @@ impl DecoderState {
240
247
pub fn process < ' a , W : io:: Write , LZB : LzBuffer < W > , R : io:: BufRead > (
241
248
& mut self ,
242
249
output : & mut LZB ,
243
- rangecoder : & mut rangecoder :: RangeDecoder < ' a , R > ,
250
+ rangecoder : & mut RangeDecoder < ' a , R > ,
244
251
) -> error:: Result < ( ) > {
245
252
self . process_mode ( output, rangecoder, ProcessingMode :: Finish )
246
253
}
@@ -249,7 +256,7 @@ impl DecoderState {
249
256
pub fn process_stream < ' a , W : io:: Write , LZB : LzBuffer < W > , R : io:: BufRead > (
250
257
& mut self ,
251
258
output : & mut LZB ,
252
- rangecoder : & mut rangecoder :: RangeDecoder < ' a , R > ,
259
+ rangecoder : & mut RangeDecoder < ' a , R > ,
253
260
) -> error:: Result < ( ) > {
254
261
self . process_mode ( output, rangecoder, ProcessingMode :: Partial )
255
262
}
@@ -263,7 +270,7 @@ impl DecoderState {
263
270
fn process_next_inner < ' a , W : io:: Write , LZB : LzBuffer < W > , R : io:: BufRead > (
264
271
& mut self ,
265
272
output : & mut LZB ,
266
- rangecoder : & mut rangecoder :: RangeDecoder < ' a , R > ,
273
+ rangecoder : & mut RangeDecoder < ' a , R > ,
267
274
update : bool ,
268
275
) -> error:: Result < ProcessingStatus > {
269
276
let pos_state = output. len ( ) & ( ( 1 << self . lzma_props . pb ) - 1 ) ;
@@ -380,7 +387,7 @@ impl DecoderState {
380
387
fn process_next < ' a , W : io:: Write , LZB : LzBuffer < W > , R : io:: BufRead > (
381
388
& mut self ,
382
389
output : & mut LZB ,
383
- rangecoder : & mut rangecoder :: RangeDecoder < ' a , R > ,
390
+ rangecoder : & mut RangeDecoder < ' a , R > ,
384
391
) -> error:: Result < ProcessingStatus > {
385
392
self . process_next_inner ( output, rangecoder, true )
386
393
}
@@ -398,15 +405,15 @@ impl DecoderState {
398
405
code : u32 ,
399
406
) -> error:: Result < ( ) > {
400
407
let mut temp = std:: io:: Cursor :: new ( buf) ;
401
- let mut rangecoder = rangecoder :: RangeDecoder :: from_parts ( & mut temp, range, code) ;
408
+ let mut rangecoder = RangeDecoder :: from_parts ( & mut temp, range, code) ;
402
409
let _ = self . process_next_inner ( output, & mut rangecoder, false ) ?;
403
410
Ok ( ( ) )
404
411
}
405
412
406
413
/// Utility function to read data into the partial input buffer.
407
414
fn read_partial_input_buf < ' a , R : io:: BufRead > (
408
415
& mut self ,
409
- rangecoder : & mut rangecoder :: RangeDecoder < ' a , R > ,
416
+ rangecoder : & mut RangeDecoder < ' a , R > ,
410
417
) -> error:: Result < ( ) > {
411
418
// Fill as much of the tmp buffer as possible
412
419
let start = self . partial_input_buf . position ( ) as usize ;
@@ -420,7 +427,7 @@ impl DecoderState {
420
427
fn process_mode < ' a , W : io:: Write , LZB : LzBuffer < W > , R : io:: BufRead > (
421
428
& mut self ,
422
429
output : & mut LZB ,
423
- rangecoder : & mut rangecoder :: RangeDecoder < ' a , R > ,
430
+ rangecoder : & mut RangeDecoder < ' a , R > ,
424
431
mode : ProcessingMode ,
425
432
) -> error:: Result < ( ) > {
426
433
loop {
@@ -461,11 +468,8 @@ impl DecoderState {
461
468
// Run the decompressor on the tmp buffer
462
469
let mut tmp_reader =
463
470
io:: Cursor :: new ( & tmp[ ..self . partial_input_buf . position ( ) as usize ] ) ;
464
- let mut tmp_rangecoder = rangecoder:: RangeDecoder :: from_parts (
465
- & mut tmp_reader,
466
- rangecoder. range ,
467
- rangecoder. code ,
468
- ) ;
471
+ let mut tmp_rangecoder =
472
+ RangeDecoder :: from_parts ( & mut tmp_reader, rangecoder. range , rangecoder. code ) ;
469
473
let res = self . process_next ( output, & mut tmp_rangecoder) ?;
470
474
471
475
// Update the actual rangecoder
@@ -514,7 +518,7 @@ impl DecoderState {
514
518
fn decode_literal < ' a , W : io:: Write , LZB : LzBuffer < W > , R : io:: BufRead > (
515
519
& mut self ,
516
520
output : & mut LZB ,
517
- rangecoder : & mut rangecoder :: RangeDecoder < ' a , R > ,
521
+ rangecoder : & mut RangeDecoder < ' a , R > ,
518
522
update : bool ,
519
523
) -> error:: Result < u8 > {
520
524
let def_prev_byte = 0u8 ;
@@ -550,7 +554,7 @@ impl DecoderState {
550
554
551
555
fn decode_distance < ' a , R : io:: BufRead > (
552
556
& mut self ,
553
- rangecoder : & mut rangecoder :: RangeDecoder < ' a , R > ,
557
+ rangecoder : & mut RangeDecoder < ' a , R > ,
554
558
length : usize ,
555
559
update : bool ,
556
560
) -> error:: Result < usize > {
0 commit comments