summaryrefslogtreecommitdiffstats
path: root/encoder_base.c
diff options
context:
space:
mode:
Diffstat (limited to 'encoder_base.c')
-rw-r--r--encoder_base.c80
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 );