summaryrefslogtreecommitdiffstats
path: root/decoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'decoder.c')
-rw-r--r--decoder.c140
1 files changed, 70 insertions, 70 deletions
diff --git a/decoder.c b/decoder.c
index a995da3..3095015 100644
--- a/decoder.c
+++ b/decoder.c
@@ -1,5 +1,5 @@
/* Lunzip - Decompressor for the lzip format
- Copyright (C) 2010-2018 Antonio Diaz Diaz.
+ Copyright (C) 2010-2019 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
@@ -115,15 +115,15 @@ void LZd_flush_data( struct LZ_decoder * const d )
static bool LZd_verify_trailer( struct LZ_decoder * const d,
struct Pretty_print * const pp )
{
- File_trailer trailer;
- int size = Rd_read_data( d->rdec, trailer, Ft_size );
+ Lzip_trailer trailer;
+ 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 < Ft_size )
+ if( size < Lt_size )
{
error = true;
if( verbosity >= 0 )
@@ -132,10 +132,10 @@ static bool LZd_verify_trailer( struct LZ_decoder * const d,
fprintf( stderr, "Trailer truncated at trailer position %d;"
" some checks may fail.\n", size );
}
- while( size < Ft_size ) trailer[size++] = 0;
+ while( size < Lt_size ) trailer[size++] = 0;
}
- td_crc = Ft_get_data_crc( trailer );
+ td_crc = Lt_get_data_crc( trailer );
if( td_crc != LZd_crc( d ) )
{
error = true;
@@ -146,7 +146,7 @@ static bool LZd_verify_trailer( struct LZ_decoder * const d,
td_crc, LZd_crc( d ) );
}
}
- td_size = Ft_get_data_size( trailer );
+ td_size = Lt_get_data_size( trailer );
if( td_size != data_size )
{
error = true;
@@ -157,7 +157,7 @@ static bool LZd_verify_trailer( struct LZ_decoder * const d,
td_size, td_size, data_size, data_size );
}
}
- tm_size = Ft_get_member_size( trailer );
+ tm_size = Lt_get_member_size( trailer );
if( tm_size != member_size )
{
error = true;
@@ -232,9 +232,11 @@ 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 */
+ 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 ) )
{
@@ -246,84 +248,82 @@ int LZd_decode_member( struct LZ_decoder * const d,
state -= ( state < 10 ) ? 3 : 6;
LZd_put_byte( d, Rd_decode_matched( rdec, bm, LZd_peek( d, rep0 ) ) );
}
+ continue;
}
- else /* match or repeated match */
+ /* match or repeated match */
+ if( Rd_decode_bit( rdec, &bm_rep[state] ) != 0 ) /* 2nd bit */
{
- int len;
- if( Rd_decode_bit( rdec, &bm_rep[state] ) != 0 ) /* 2nd bit */
+ if( Rd_decode_bit( rdec, &bm_rep0[state] ) == 0 ) /* 3rd bit */
{
- if( Rd_decode_bit( rdec, &bm_rep0[state] ) == 0 ) /* 3rd bit */
- {
- if( Rd_decode_bit( rdec, &bm_len[state][pos_state] ) == 0 ) /* 4th bit */
- { state = St_set_short_rep( state );
- LZd_put_byte( d, LZd_peek( d, rep0 ) ); continue; }
- }
+ if( Rd_decode_bit( rdec, &bm_len[state][pos_state] ) == 0 ) /* 4th bit */
+ { state = St_set_short_rep( state );
+ LZd_put_byte( d, LZd_peek( d, rep0 ) ); continue; }
+ }
+ else
+ {
+ unsigned distance;
+ if( Rd_decode_bit( rdec, &bm_rep1[state] ) == 0 ) /* 4th bit */
+ distance = rep1;
else
{
- unsigned distance;
- if( Rd_decode_bit( rdec, &bm_rep1[state] ) == 0 ) /* 4th bit */
- distance = rep1;
+ if( Rd_decode_bit( rdec, &bm_rep2[state] ) == 0 ) /* 5th bit */
+ distance = rep2;
else
- {
- if( Rd_decode_bit( rdec, &bm_rep2[state] ) == 0 ) /* 5th bit */
- distance = rep2;
- else
- { distance = rep3; rep3 = rep2; }
- rep2 = rep1;
- }
- rep1 = rep0;
- rep0 = distance;
+ { distance = rep3; rep3 = rep2; }
+ rep2 = rep1;
}
- state = St_set_rep( state );
- len = min_match_len + Rd_decode_len( rdec, &rep_len_model, pos_state );
+ rep1 = rep0;
+ rep0 = distance;
}
- else /* match */
+ state = St_set_rep( state );
+ len = min_match_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)] );
+ if( distance >= start_dis_model )
{
- 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)] );
- if( distance >= start_dis_model )
+ const unsigned dis_slot = distance;
+ const int direct_bits = ( dis_slot >> 1 ) - 1;
+ distance = ( 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 );
+ else
{
- const unsigned dis_slot = distance;
- const int direct_bits = ( dis_slot >> 1 ) - 1;
- distance = ( 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 );
- 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 */
{
- 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 */
+ Rd_normalize( rdec );
+ LZd_flush_data( d );
+ if( len == min_match_len ) /* End Of Stream marker */
+ {
+ if( LZd_verify_trailer( d, pp ) ) return 0; else return 3;
+ }
+ if( len == min_match_len + 1 ) /* Sync Flush marker */
+ {
+ Rd_load( rdec ); continue;
+ }
+ if( verbosity >= 0 )
{
- Rd_normalize( rdec );
- LZd_flush_data( d );
- if( len == min_match_len ) /* End Of Stream marker */
- {
- if( LZd_verify_trailer( d, pp ) ) return 0; else return 3;
- }
- if( len == min_match_len + 1 ) /* Sync Flush marker */
- {
- Rd_load( rdec ); continue;
- }
- if( verbosity >= 0 )
- {
- Pp_show_msg( pp, 0 );
- fprintf( stderr, "Unsupported marker code '%d'\n", len );
- }
- return 4;
+ 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 ||
- ( rep0 >= LZd_data_position( d ) && !d->pos_wrapped_dic ) )
- { LZd_flush_data( d ); return 1; }
}
- copy_block( d, rep0, len );
+ rep3 = rep2; rep2 = rep1; rep1 = rep0; rep0 = distance;
+ state = St_set_match( state );
+ if( rep0 >= d->dictionary_size ||
+ ( rep0 >= LZd_data_position( d ) && !d->pos_wrapped_dic ) )
+ { LZd_flush_data( d ); return 1; }
}
+ copy_block( d, rep0, len );
}
LZd_flush_data( d );
return 2;