diff options
Diffstat (limited to 'decoder.c')
-rw-r--r-- | decoder.c | 43 |
1 files changed, 16 insertions, 27 deletions
@@ -1,5 +1,5 @@ /* Lunzip - Decompressor for the lzip format - Copyright (C) 2010-2021 Antonio Diaz Diaz. + Copyright (C) 2010-2022 Antonio Diaz Diaz. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -32,8 +32,8 @@ CRC32 crc32; -/* Returns the number of bytes really read. - If (returned value < size) and (errno == 0), means EOF was reached. +/* Return the number of bytes really read. + If (value returned < size) and (errno == 0), means EOF was reached. */ int readblock( const int fd, uint8_t * const buf, const int size ) { @@ -51,8 +51,8 @@ int readblock( const int fd, uint8_t * const buf, const int size ) } -/* Returns the number of bytes really written. - If (returned value < size), it is always an error. +/* Return the number of bytes really written. + If (value returned < size), it is always an error. */ static int writeblock( const int fd, const uint8_t * const buf, const int size ) { @@ -118,8 +118,6 @@ static bool LZd_verify_trailer( struct LZ_decoder * const d, int size = Rd_read_data( d->rdec, trailer, Lt_size ); const unsigned long long data_size = LZd_data_position( d ); const unsigned long long member_size = Rd_member_position( d->rdec ); - unsigned td_crc; - unsigned long long td_size, tm_size; bool error = false; if( size < Lt_size ) @@ -134,7 +132,7 @@ static bool LZd_verify_trailer( struct LZ_decoder * const d, while( size < Lt_size ) trailer[size++] = 0; } - td_crc = Lt_get_data_crc( trailer ); + const unsigned td_crc = Lt_get_data_crc( trailer ); if( td_crc != LZd_crc( d ) ) { error = true; @@ -145,7 +143,7 @@ static bool LZd_verify_trailer( struct LZ_decoder * const d, td_crc, LZd_crc( d ) ); } } - td_size = Lt_get_data_size( trailer ); + const unsigned long long td_size = Lt_get_data_size( trailer ); if( td_size != data_size ) { error = true; @@ -156,7 +154,7 @@ static bool LZd_verify_trailer( struct LZ_decoder * const d, td_size, td_size, data_size, data_size ); } } - tm_size = Lt_get_member_size( trailer ); + const unsigned long long tm_size = Lt_get_member_size( trailer ); if( tm_size != member_size ) { error = true; @@ -192,10 +190,6 @@ int LZd_decode_member( struct LZ_decoder * const d, struct Pretty_print * const pp ) { struct Range_decoder * const rdec = d->rdec; - void (* const copy_block) - ( struct LZ_decoder * const d, const unsigned distance, unsigned len ) = - ( d->buffer_size >= d->dictionary_size ) ? - &LZd_copy_block : &LZd_copy_block2; Bit_model bm_literal[1<<literal_context_bits][0x300]; Bit_model bm_match[states][pos_states]; Bit_model bm_rep[states]; @@ -213,6 +207,7 @@ int LZd_decode_member( struct LZ_decoder * const d, unsigned rep2 = 0; /* repeated distances */ unsigned rep3 = 0; State state = 0; + const bool full_buffer = d->buffer_size >= d->dictionary_size; Bm_array_init( bm_literal[0], (1 << literal_context_bits) * 0x300 ); Bm_array_init( bm_match[0], states * pos_states ); @@ -230,25 +225,19 @@ int LZd_decode_member( struct LZ_decoder * const d, Rd_load( rdec ); while( !Rd_finished( rdec ) ) { - int len; const int pos_state = LZd_data_position( d ) & pos_state_mask; if( Rd_decode_bit( rdec, &bm_match[state][pos_state] ) == 0 ) /* 1st bit */ { /* literal byte */ Bit_model * const bm = bm_literal[get_lit_state(LZd_peek_prev( d ))]; - if( St_is_char( state ) ) - { - state -= ( state < 4 ) ? state : 3; + if( ( state = St_set_char( state ) ) < 4 ) LZd_put_byte( d, Rd_decode_tree8( rdec, bm ) ); - } else - { - state -= ( state < 10 ) ? 3 : 6; LZd_put_byte( d, Rd_decode_matched( rdec, bm, LZd_peek( d, rep0 ) ) ); - } continue; } /* match or repeated match */ + int len; if( Rd_decode_bit( rdec, &bm_rep[state] ) != 0 ) /* 2nd bit */ { if( Rd_decode_bit( rdec, &bm_rep0[state] ) == 0 ) /* 3rd bit */ @@ -274,13 +263,12 @@ int LZd_decode_member( struct LZ_decoder * const d, rep0 = distance; } state = St_set_rep( state ); - len = min_match_len + Rd_decode_len( rdec, &rep_len_model, pos_state ); + len = Rd_decode_len( rdec, &rep_len_model, pos_state ); } else /* match */ { - unsigned distance; - len = min_match_len + Rd_decode_len( rdec, &match_len_model, pos_state ); - distance = Rd_decode_tree6( rdec, bm_dis_slot[get_len_state(len)] ); + len = Rd_decode_len( rdec, &match_len_model, pos_state ); + unsigned distance = Rd_decode_tree6( rdec, bm_dis_slot[get_len_state(len)] ); if( distance >= start_dis_model ) { const unsigned dis_slot = distance; @@ -321,7 +309,8 @@ int LZd_decode_member( struct LZ_decoder * const d, ( !d->pos_wrapped && rep0 >= LZd_data_position( d ) ) ) { LZd_flush_data( d ); return 1; } } - copy_block( d, rep0, len ); + if( full_buffer || rep0 < d->buffer_size ) LZd_copy_block( d, rep0, len ); + else LZd_copy_block2( d, rep0, len ); } LZd_flush_data( d ); return 2; |