summaryrefslogtreecommitdiffstats
path: root/decoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'decoder.c')
-rw-r--r--decoder.c43
1 files changed, 16 insertions, 27 deletions
diff --git a/decoder.c b/decoder.c
index 63d30ea..b52b35f 100644
--- a/decoder.c
+++ b/decoder.c
@@ -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;