diff options
Diffstat (limited to 'decoder.c')
-rw-r--r-- | decoder.c | 63 |
1 files changed, 26 insertions, 37 deletions
@@ -78,14 +78,14 @@ unsigned seek_read_back( const int fd, uint8_t * const buf, const int size, } -bool Rd_read_block( struct Range_decoder * const rdec ) +bool Rd_read_block( Range_decoder * const rdec ) { if( !rdec->at_stream_end ) { rdec->stream_pos = readblock( rdec->infd, rdec->buffer, rd_buffer_size ); if( rdec->stream_pos != rd_buffer_size && errno ) { show_error( "Read error", errno, false ); cleanup_and_fail( 1 ); } - rdec->at_stream_end = ( rdec->stream_pos < rd_buffer_size ); + rdec->at_stream_end = rdec->stream_pos < rd_buffer_size; rdec->partial_member_pos += rdec->pos; rdec->pos = 0; show_dprogress( 0, 0, 0, 0 ); @@ -94,7 +94,7 @@ bool Rd_read_block( struct Range_decoder * const rdec ) } -void LZd_flush_data( struct LZ_decoder * const d ) +void LZd_flush_data( LZ_decoder * const d ) { if( d->pos > d->stream_pos ) { @@ -102,7 +102,7 @@ void LZd_flush_data( struct LZ_decoder * const d ) CRC32_update_buf( &d->crc, d->buffer + d->stream_pos, size ); if( d->outfd >= 0 && writeblock( d->outfd, d->buffer + d->stream_pos, size ) != size ) - { show_error( "Write error", errno, false ); cleanup_and_fail( 1 ); } + { show_error( write_error_msg, errno, false ); cleanup_and_fail( 1 ); } if( d->pos >= d->buffer_size ) { d->partial_data_pos += d->pos; d->pos = 0; if( d->partial_data_pos >= d->dictionary_size ) d->pos_wrapped = true; } @@ -111,9 +111,7 @@ void LZd_flush_data( struct LZ_decoder * const d ) } -static int LZd_check_trailer( struct LZ_decoder * const d, - struct Pretty_print * const pp, - const bool ignore_empty ) +static bool LZd_check_trailer( LZ_decoder * const d, Pretty_print * const pp ) { Lzip_trailer trailer; int size = Rd_read_data( d->rdec, trailer, Lt_size ); @@ -158,8 +156,7 @@ static int LZd_check_trailer( struct LZ_decoder * const d, fprintf( stderr, "Member size mismatch; stored %llu (0x%llX), computed %llu (0x%llX)\n", tm_size, tm_size, member_size, member_size ); } } - if( error ) return 3; - if( !ignore_empty && data_size == 0 ) return 5; + if( error ) return false; if( verbosity >= 2 ) { if( verbosity >= 4 ) show_header( d->dictionary_size ); @@ -174,18 +171,16 @@ static int LZd_check_trailer( struct LZ_decoder * const d, if( verbosity >= 3 ) fprintf( stderr, "%9llu out, %8llu in. ", data_size, member_size ); } - return 0; + return true; } /* Return value: 0 = OK, 1 = decoder error, 2 = unexpected EOF, 3 = trailer error, 4 = unknown marker found, - 5 = empty member found, 6 = marked member found. */ -int LZd_decode_member( struct LZ_decoder * const d, - const struct Cl_options * const cl_opts, - struct Pretty_print * const pp ) + 5 = nonzero first LZMA byte found. */ +int LZd_decode_member( LZ_decoder * const d, Pretty_print * const pp ) { - struct Range_decoder * const rdec = d->rdec; + Range_decoder * const rdec = d->rdec; Bit_model bm_literal[1<<literal_context_bits][0x300]; Bit_model bm_match[states][pos_states]; Bit_model bm_rep[states]; @@ -196,8 +191,8 @@ int LZd_decode_member( struct LZ_decoder * const d, Bit_model bm_dis_slot[len_states][1<<dis_slot_bits]; Bit_model bm_dis[modeled_distances-end_dis_model+1]; Bit_model bm_align[dis_align_size]; - struct Len_model match_len_model; - struct Len_model rep_len_model; + Len_model match_len_model; + Len_model rep_len_model; unsigned rep0 = 0; /* rep[0-3] latest four distances */ unsigned rep1 = 0; /* used for efficient coding of */ unsigned rep2 = 0; /* repeated distances */ @@ -218,7 +213,7 @@ int LZd_decode_member( struct LZ_decoder * const d, Lm_init( &match_len_model ); Lm_init( &rep_len_model ); - if( !Rd_load( rdec, cl_opts->ignore_marking ) ) return 6; + if( !Rd_load( rdec ) ) return 5; while( !Rd_finished( rdec ) ) { const int pos_state = LZd_data_position( d ) & pos_state_mask; @@ -263,39 +258,33 @@ int LZd_decode_member( struct LZ_decoder * const d, } else /* match */ { + rep3 = rep2; rep2 = rep1; rep1 = rep0; 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 ) + rep0 = Rd_decode_tree6( rdec, bm_dis_slot[get_len_state(len)] ); + if( rep0 >= start_dis_model ) { - const unsigned dis_slot = distance; + const unsigned dis_slot = rep0; const int direct_bits = ( dis_slot >> 1 ) - 1; - distance = ( 2 | ( dis_slot & 1 ) ) << direct_bits; + rep0 = ( 2 | ( dis_slot & 1 ) ) << direct_bits; if( dis_slot < end_dis_model ) - distance += Rd_decode_tree_reversed( rdec, - bm_dis + ( distance - dis_slot ), direct_bits ); + rep0 += Rd_decode_tree_reversed( rdec, bm_dis + ( rep0 - dis_slot ), + direct_bits ); else { - distance += - Rd_decode( rdec, direct_bits - dis_align_bits ) << dis_align_bits; - distance += Rd_decode_tree_reversed4( rdec, bm_align ); - if( distance == 0xFFFFFFFFU ) /* marker found */ + rep0 += Rd_decode( rdec, direct_bits - dis_align_bits ) << dis_align_bits; + rep0 += Rd_decode_tree_reversed4( rdec, bm_align ); + if( rep0 == 0xFFFFFFFFU ) /* marker found */ { Rd_normalize( rdec ); LZd_flush_data( d ); if( len == min_match_len ) /* End Of Stream marker */ - return LZd_check_trailer( d, pp, cl_opts->ignore_empty ); - if( len == min_match_len + 1 ) /* Sync Flush marker */ - { Rd_load( rdec, true ); continue; } - if( verbosity >= 0 ) - { - Pp_show_msg( pp, 0 ); - fprintf( stderr, "Unsupported marker code '%d'\n", len ); - } + { if( LZd_check_trailer( d, pp ) ) return 0; else return 3; } + if( verbosity >= 0 ) { Pp_show_msg( pp, 0 ); + fprintf( stderr, "Unsupported marker code '%d'\n", len ); } return 4; } } } - rep3 = rep2; rep2 = rep1; rep1 = rep0; rep0 = distance; state = St_set_match( state ); if( rep0 >= d->dictionary_size || ( !d->pos_wrapped && rep0 >= LZd_data_position( d ) ) ) |