diff options
Diffstat (limited to 'encoder_base.c')
-rw-r--r-- | encoder_base.c | 80 |
1 files changed, 38 insertions, 42 deletions
diff --git a/encoder_base.c b/encoder_base.c index d385f2c..d2ed53c 100644 --- a/encoder_base.c +++ b/encoder_base.c @@ -1,20 +1,20 @@ -/* 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. */ static bool Mb_normalize_pos( struct Matchfinder_base * const mb ) @@ -47,7 +47,6 @@ static bool Mb_init( struct Matchfinder_base * const mb, const int before_size, { const int buffer_size_limit = ( dict_factor * dict_size ) + before_size + after_size; - unsigned size; int i; mb->partial_data_pos = 0; @@ -58,7 +57,7 @@ static bool Mb_init( struct Matchfinder_base * const mb, const int before_size, mb->stream_pos = 0; mb->num_prev_positions23 = num_prev_positions23; mb->at_stream_end = false; - mb->flushing = false; + mb->sync_flush_pending = false; mb->buffer_size = max( 65536, buffer_size_limit ); mb->buffer = (uint8_t *)malloc( mb->buffer_size ); @@ -66,10 +65,9 @@ static bool Mb_init( struct Matchfinder_base * const mb, const int before_size, mb->saved_dictionary_size = dict_size; mb->dictionary_size = dict_size; mb->pos_limit = mb->buffer_size - after_size; - size = 1 << max( 16, real_bits( mb->dictionary_size - 1 ) - 2 ); - if( mb->dictionary_size > 1 << 26 ) /* 64 MiB */ - size >>= 1; - mb->key4_mask = size - 1; + unsigned size = 1 << max( 16, real_bits( mb->dictionary_size - 1 ) - 2 ); + if( mb->dictionary_size > 1 << 26 ) size >>= 1; /* 64 MiB */ + mb->key4_mask = size - 1; /* increases with dictionary size */ size += num_prev_positions23; mb->num_prev_positions = size; @@ -88,8 +86,7 @@ static bool Mb_init( struct Matchfinder_base * const mb, const int before_size, static void Mb_adjust_array( struct Matchfinder_base * const mb ) { int size = 1 << max( 16, real_bits( mb->dictionary_size - 1 ) - 2 ); - if( mb->dictionary_size > 1 << 26 ) /* 64 MiB */ - size >>= 1; + if( mb->dictionary_size > 1 << 26 ) size >>= 1; /* 64 MiB */ mb->key4_mask = size - 1; size += mb->num_prev_positions23; mb->num_prev_positions = size; @@ -118,7 +115,7 @@ static void Mb_reset( struct Matchfinder_base * const mb ) mb->pos = 0; mb->cyclic_pos = 0; mb->at_stream_end = false; - mb->flushing = false; + mb->sync_flush_pending = false; mb->dictionary_size = mb->saved_dictionary_size; Mb_adjust_array( mb ); mb->pos_limit = mb->buffer_size - mb->after_size; @@ -126,56 +123,55 @@ static void Mb_reset( struct Matchfinder_base * const mb ) } - /* End Of Stream mark => (dis == 0xFFFFFFFFU, len == min_match_len) */ +/* End Of Stream marker => (dis == 0xFFFFFFFFU, len == min_match_len) */ static void LZeb_try_full_flush( struct LZ_encoder_base * const eb ) { - int i; + if( eb->member_finished || Cb_free_bytes( &eb->renc.cb ) < + max_marker_size + eb->renc.ff_count + Lt_size ) return; + eb->member_finished = true; const int pos_state = Mb_data_position( &eb->mb ) & pos_state_mask; const State state = eb->state; - Lzip_trailer trailer; - if( eb->member_finished || - Cb_free_bytes( &eb->renc.cb ) < max_marker_size + eb->renc.ff_count + Lt_size ) - return; - eb->member_finished = true; Re_encode_bit( &eb->renc, &eb->bm_match[state][pos_state], 1 ); Re_encode_bit( &eb->renc, &eb->bm_rep[state], 0 ); LZeb_encode_pair( eb, 0xFFFFFFFFU, min_match_len, pos_state ); Re_flush( &eb->renc ); + Lzip_trailer trailer; Lt_set_data_crc( trailer, LZeb_crc( eb ) ); Lt_set_data_size( trailer, Mb_data_position( &eb->mb ) ); Lt_set_member_size( trailer, Re_member_position( &eb->renc ) + Lt_size ); - for( i = 0; i < Lt_size; ++i ) - Cb_put_byte( &eb->renc.cb, trailer[i] ); + int i; for( i = 0; i < Lt_size; ++i ) Cb_put_byte( &eb->renc.cb, trailer[i] ); } - /* Sync Flush mark => (dis == 0xFFFFFFFFU, len == min_match_len + 1) */ -static bool LZeb_sync_flush( struct LZ_encoder_base * const eb ) +/* Sync Flush marker => (dis == 0xFFFFFFFFU, len == min_match_len + 1) */ +static void LZeb_try_sync_flush( struct LZ_encoder_base * const eb ) { - int i; + const unsigned min_size = eb->renc.ff_count + max_marker_size; + if( eb->member_finished || + Cb_free_bytes( &eb->renc.cb ) < min_size + max_marker_size ) return; + eb->mb.sync_flush_pending = false; + const unsigned long long old_mpos = Re_member_position( &eb->renc ); const int pos_state = Mb_data_position( &eb->mb ) & pos_state_mask; const State state = eb->state; - if( eb->member_finished || - Cb_free_bytes( &eb->renc.cb ) < (2 * max_marker_size) + eb->renc.ff_count ) - return false; - for( i = 0; i < 2; ++i ) /* 2 consecutive markers guarantee decoding */ - { + do { /* size of markers must be >= rd_min_available_bytes + 5 */ Re_encode_bit( &eb->renc, &eb->bm_match[state][pos_state], 1 ); Re_encode_bit( &eb->renc, &eb->bm_rep[state], 0 ); LZeb_encode_pair( eb, 0xFFFFFFFFU, min_match_len + 1, pos_state ); Re_flush( &eb->renc ); } - return true; + while( Re_member_position( &eb->renc ) - old_mpos < min_size ); } static void LZeb_reset( struct LZ_encoder_base * const eb, const unsigned long long member_size ) { + const unsigned long long min_member_size = min_dictionary_size; + const unsigned long long max_member_size = 0x0008000000000000ULL; /* 2 PiB */ int i; Mb_reset( &eb->mb ); - eb->member_size_limit = - min( member_size, 0x0008000000000000ULL ) - Lt_size - max_marker_size; + eb->member_size_limit = min( max( min_member_size, member_size ), + max_member_size ) - Lt_size - max_marker_size; eb->crc = 0xFFFFFFFFU; Bm_array_init( eb->bm_literal[0], (1 << literal_context_bits) * 0x300 ); Bm_array_init( eb->bm_match[0], states * pos_states ); |