summaryrefslogtreecommitdiffstats
path: root/decoder.h
diff options
context:
space:
mode:
Diffstat (limited to 'decoder.h')
-rw-r--r--decoder.h173
1 files changed, 107 insertions, 66 deletions
diff --git a/decoder.h b/decoder.h
index 1873d5e..4b91fec 100644
--- a/decoder.h
+++ b/decoder.h
@@ -1,23 +1,23 @@
-/* Lzlib - Compression library for the lzip format
- Copyright (C) 2009-2019 Antonio Diaz Diaz.
+/* Lzlib - Compression library for the lzip format
+ Copyright (C) 2009-2024 Antonio Diaz Diaz.
- This library is free software. Redistribution and use in source and
- binary forms, with or without modification, are permitted provided
- that the following conditions are met:
+ This library is free software. Redistribution and use in source and
+ binary forms, with or without modification, are permitted provided
+ that the following conditions are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions, and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions, and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
-enum { rd_min_available_bytes = 8 };
+enum { rd_min_available_bytes = 10 };
struct Range_decoder
{
@@ -50,7 +50,7 @@ static inline void Rd_finish( struct Range_decoder * const rdec )
{ rdec->at_stream_end = true; }
static inline bool Rd_enough_available_bytes( const struct Range_decoder * const rdec )
- { return ( Cb_used_bytes( &rdec->cb ) >= rd_min_available_bytes ); }
+ { return Cb_used_bytes( &rdec->cb ) >= rd_min_available_bytes; }
static inline unsigned Rd_available_bytes( const struct Range_decoder * const rdec )
{ return Cb_used_bytes( &rdec->cb ); }
@@ -72,8 +72,8 @@ static inline void Rd_reset( struct Range_decoder * const rdec )
rdec->member_position = 0; rdec->at_stream_end = false; }
-/* Seeks a member header and updates 'get'. '*skippedp' is set to the
- number of bytes skipped. Returns true if it finds a valid header.
+/* Seek for a member header and update 'get'. Set '*skippedp' to the number
+ of bytes skipped. Return true if a valid header is found.
*/
static bool Rd_find_header( struct Range_decoder * const rdec,
unsigned * const skippedp )
@@ -92,7 +92,7 @@ static bool Rd_find_header( struct Range_decoder * const rdec,
header[i] = rdec->cb.buffer[get];
if( ++get >= rdec->cb.buffer_size ) get = 0;
}
- if( Lh_verify( header ) ) return true;
+ if( Lh_check( header ) ) return true;
}
if( ++rdec->cb.get >= rdec->cb.buffer_size ) rdec->cb.get = 0;
++*skippedp;
@@ -133,18 +133,16 @@ static inline bool Rd_unread_data( struct Range_decoder * const rdec,
return true;
}
-static bool Rd_try_reload( struct Range_decoder * const rdec, const bool force )
+static bool Rd_try_reload( struct Range_decoder * const rdec )
{
- if( force ) rdec->reload_pending = true;
if( rdec->reload_pending && Rd_available_bytes( rdec ) >= 5 )
{
- int i;
rdec->reload_pending = false;
rdec->code = 0;
- for( i = 0; i < 5; ++i )
- rdec->code = (rdec->code << 8) | Rd_get_byte( rdec );
rdec->range = 0xFFFFFFFFU;
- rdec->code &= rdec->range; /* make sure that first byte is discarded */
+ Rd_get_byte( rdec ); /* discard first byte of the LZMA stream */
+ int i; for( i = 0; i < 4; ++i )
+ rdec->code = (rdec->code << 8) | Rd_get_byte( rdec );
}
return !rdec->reload_pending;
}
@@ -162,13 +160,12 @@ static inline unsigned Rd_decode( struct Range_decoder * const rdec,
int i;
for( i = num_bits; i > 0; --i )
{
- bool bit;
Rd_normalize( rdec );
rdec->range >>= 1;
/* symbol <<= 1; */
/* if( rdec->code >= rdec->range ) { rdec->code -= rdec->range; symbol |= 1; } */
- bit = ( rdec->code >= rdec->range );
- symbol = ( symbol << 1 ) + bit;
+ const bool bit = ( rdec->code >= rdec->range );
+ symbol <<= 1; symbol += bit;
rdec->code -= rdec->range & ( 0U - bit );
}
return symbol;
@@ -177,44 +174,75 @@ static inline unsigned Rd_decode( struct Range_decoder * const rdec,
static inline unsigned Rd_decode_bit( struct Range_decoder * const rdec,
Bit_model * const probability )
{
- uint32_t bound;
Rd_normalize( rdec );
- bound = ( rdec->range >> bit_model_total_bits ) * *probability;
+ const uint32_t bound = ( rdec->range >> bit_model_total_bits ) * *probability;
if( rdec->code < bound )
{
rdec->range = bound;
- *probability += (bit_model_total - *probability) >> bit_model_move_bits;
+ *probability += ( bit_model_total - *probability ) >> bit_model_move_bits;
return 0;
}
else
{
- rdec->range -= bound;
rdec->code -= bound;
+ rdec->range -= bound;
*probability -= *probability >> bit_model_move_bits;
return 1;
}
}
-static inline unsigned Rd_decode_tree3( struct Range_decoder * const rdec,
- Bit_model bm[] )
+static inline void Rd_decode_symbol_bit( struct Range_decoder * const rdec,
+ Bit_model * const probability, unsigned * symbol )
{
- unsigned symbol = 1;
- symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] );
- symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] );
- symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] );
- return symbol & 7;
+ Rd_normalize( rdec );
+ *symbol <<= 1;
+ const uint32_t bound = ( rdec->range >> bit_model_total_bits ) * *probability;
+ if( rdec->code < bound )
+ {
+ rdec->range = bound;
+ *probability += ( bit_model_total - *probability ) >> bit_model_move_bits;
+ }
+ else
+ {
+ rdec->code -= bound;
+ rdec->range -= bound;
+ *probability -= *probability >> bit_model_move_bits;
+ *symbol |= 1;
+ }
+ }
+
+static inline void Rd_decode_symbol_bit_reversed( struct Range_decoder * const rdec,
+ Bit_model * const probability, unsigned * model,
+ unsigned * symbol, const int i )
+ {
+ Rd_normalize( rdec );
+ *model <<= 1;
+ const uint32_t bound = ( rdec->range >> bit_model_total_bits ) * *probability;
+ if( rdec->code < bound )
+ {
+ rdec->range = bound;
+ *probability += ( bit_model_total - *probability ) >> bit_model_move_bits;
+ }
+ else
+ {
+ rdec->code -= bound;
+ rdec->range -= bound;
+ *probability -= *probability >> bit_model_move_bits;
+ *model |= 1;
+ *symbol |= 1 << i;
+ }
}
static inline unsigned Rd_decode_tree6( struct Range_decoder * const rdec,
Bit_model bm[] )
{
unsigned symbol = 1;
- symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] );
- symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] );
- symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] );
- symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] );
- symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] );
- symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] );
+ Rd_decode_symbol_bit( rdec, &bm[symbol], &symbol );
+ Rd_decode_symbol_bit( rdec, &bm[symbol], &symbol );
+ Rd_decode_symbol_bit( rdec, &bm[symbol], &symbol );
+ Rd_decode_symbol_bit( rdec, &bm[symbol], &symbol );
+ Rd_decode_symbol_bit( rdec, &bm[symbol], &symbol );
+ Rd_decode_symbol_bit( rdec, &bm[symbol], &symbol );
return symbol & 0x3F;
}
@@ -222,9 +250,14 @@ static inline unsigned Rd_decode_tree8( struct Range_decoder * const rdec,
Bit_model bm[] )
{
unsigned symbol = 1;
- int i;
- for( i = 0; i < 8; ++i )
- symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] );
+ Rd_decode_symbol_bit( rdec, &bm[symbol], &symbol );
+ Rd_decode_symbol_bit( rdec, &bm[symbol], &symbol );
+ Rd_decode_symbol_bit( rdec, &bm[symbol], &symbol );
+ Rd_decode_symbol_bit( rdec, &bm[symbol], &symbol );
+ Rd_decode_symbol_bit( rdec, &bm[symbol], &symbol );
+ Rd_decode_symbol_bit( rdec, &bm[symbol], &symbol );
+ Rd_decode_symbol_bit( rdec, &bm[symbol], &symbol );
+ Rd_decode_symbol_bit( rdec, &bm[symbol], &symbol );
return symbol & 0xFF;
}
@@ -236,24 +269,19 @@ Rd_decode_tree_reversed( struct Range_decoder * const rdec,
unsigned symbol = 0;
int i;
for( i = 0; i < num_bits; ++i )
- {
- const unsigned bit = Rd_decode_bit( rdec, &bm[model] );
- model = ( model << 1 ) + bit;
- symbol |= ( bit << i );
- }
+ Rd_decode_symbol_bit_reversed( rdec, &bm[model], &model, &symbol, i );
return symbol;
}
static inline unsigned
Rd_decode_tree_reversed4( struct Range_decoder * const rdec, Bit_model bm[] )
{
- unsigned symbol = Rd_decode_bit( rdec, &bm[1] );
- unsigned model = 2 + symbol;
- unsigned bit = Rd_decode_bit( rdec, &bm[model] );
- model = ( model << 1 ) + bit; symbol |= ( bit << 1 );
- bit = Rd_decode_bit( rdec, &bm[model] );
- model = ( model << 1 ) + bit; symbol |= ( bit << 2 );
- symbol |= ( Rd_decode_bit( rdec, &bm[model] ) << 3 );
+ unsigned model = 1;
+ unsigned symbol = 0;
+ Rd_decode_symbol_bit_reversed( rdec, &bm[model], &model, &symbol, 0 );
+ Rd_decode_symbol_bit_reversed( rdec, &bm[model], &model, &symbol, 1 );
+ Rd_decode_symbol_bit_reversed( rdec, &bm[model], &model, &symbol, 2 );
+ Rd_decode_symbol_bit_reversed( rdec, &bm[model], &model, &symbol, 3 );
return symbol;
}
@@ -266,7 +294,7 @@ static inline unsigned Rd_decode_matched( struct Range_decoder * const rdec,
{
const unsigned match_bit = ( match_byte <<= 1 ) & mask;
const unsigned bit = Rd_decode_bit( rdec, &bm[symbol+match_bit+mask] );
- symbol = ( symbol << 1 ) + bit;
+ symbol <<= 1; symbol += bit;
if( symbol > 0xFF ) return symbol & 0xFF;
mask &= ~(match_bit ^ (bit << 8)); /* if( match_bit != bit ) mask = 0; */
}
@@ -276,11 +304,24 @@ static inline unsigned Rd_decode_len( struct Range_decoder * const rdec,
struct Len_model * const lm,
const int pos_state )
{
+ Bit_model * bm;
+ unsigned mask, offset, symbol = 1;
+
if( Rd_decode_bit( rdec, &lm->choice1 ) == 0 )
- return Rd_decode_tree3( rdec, lm->bm_low[pos_state] );
+ { bm = lm->bm_low[pos_state]; mask = 7; offset = 0; goto len3; }
if( Rd_decode_bit( rdec, &lm->choice2 ) == 0 )
- return len_low_symbols + Rd_decode_tree3( rdec, lm->bm_mid[pos_state] );
- return len_low_symbols + len_mid_symbols + Rd_decode_tree8( rdec, lm->bm_high );
+ { bm = lm->bm_mid[pos_state]; mask = 7; offset = len_low_symbols; goto len3; }
+ bm = lm->bm_high; mask = 0xFF; offset = len_low_symbols + len_mid_symbols;
+ Rd_decode_symbol_bit( rdec, &bm[symbol], &symbol );
+ Rd_decode_symbol_bit( rdec, &bm[symbol], &symbol );
+ Rd_decode_symbol_bit( rdec, &bm[symbol], &symbol );
+ Rd_decode_symbol_bit( rdec, &bm[symbol], &symbol );
+ Rd_decode_symbol_bit( rdec, &bm[symbol], &symbol );
+len3:
+ Rd_decode_symbol_bit( rdec, &bm[symbol], &symbol );
+ Rd_decode_symbol_bit( rdec, &bm[symbol], &symbol );
+ Rd_decode_symbol_bit( rdec, &bm[symbol], &symbol );
+ return ( symbol & mask ) + min_match_len + offset;
}
@@ -293,8 +334,8 @@ struct LZ_decoder
struct Range_decoder * rdec;
unsigned dictionary_size;
uint32_t crc;
+ bool check_trailer_pending;
bool member_finished;
- bool verify_trailer_pending;
bool pos_wrapped;
unsigned rep0; /* rep[0-3] latest four distances */
unsigned rep1; /* used for efficient coding of */
@@ -382,8 +423,8 @@ static inline bool LZd_init( struct LZ_decoder * const d,
d->rdec = rde;
d->dictionary_size = dict_size;
d->crc = 0xFFFFFFFFU;
+ d->check_trailer_pending = false;
d->member_finished = false;
- d->verify_trailer_pending = false;
d->pos_wrapped = false;
/* prev_byte of first byte; also for LZd_peek( 0 ) on corrupt file */
d->cb.buffer[d->cb.buffer_size-1] = 0;
@@ -412,7 +453,7 @@ static inline void LZd_free( struct LZ_decoder * const d )
{ Cb_free( &d->cb ); }
static inline bool LZd_member_finished( const struct LZ_decoder * const d )
- { return ( d->member_finished && Cb_empty( &d->cb ) ); }
+ { return d->member_finished && Cb_empty( &d->cb ); }
static inline unsigned LZd_crc( const struct LZ_decoder * const d )
{ return d->crc ^ 0xFFFFFFFFU; }