1
0
Fork 0

Adding upstream version 0.4.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-20 15:54:58 +01:00
parent 2e28a50fca
commit 62f856b64f
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
16 changed files with 536 additions and 317 deletions

View file

@ -96,7 +96,7 @@ inline int price_symbol( const Bit_model bm[], int symbol, const int num_bits )
{
const int bit = symbol & 1;
symbol >>= 1;
price += price_bit( bm[symbol-1], bit );
price += price_bit( bm[symbol], bit );
}
return price;
}
@ -110,7 +110,7 @@ inline int price_symbol_reversed( const Bit_model bm[], int symbol,
{
const int bit = symbol & 1;
symbol >>= 1;
price += price_bit( bm[model-1], bit );
price += price_bit( bm[model], bit );
model = ( model << 1 ) | bit;
}
return price;
@ -126,14 +126,14 @@ inline int price_matched( const Bit_model bm[], const int symbol,
{
const int match_bit = ( match_byte >> i ) & 1;
const int bit = ( symbol >> i ) & 1;
price += price_bit( bm[(match_bit<<8)+model+0xFF], bit );
price += price_bit( bm[(match_bit<<8)+model+0x100], bit );
model = ( model << 1 ) | bit;
if( match_bit != bit )
{
while( --i >= 0 )
{
const int bit = ( symbol >> i ) & 1;
price += price_bit( bm[model-1], bit );
price += price_bit( bm[model], bit );
model = ( model << 1 ) | bit;
}
break;
@ -166,32 +166,7 @@ class Matchfinder
bool at_stream_end_; // stream_pos shows real end of file
public:
Matchfinder( const int dict_size, const int len_limit )
:
partial_data_pos( 0 ),
dictionary_size_( dict_size ),
after_size( max_num_trials + max_match_len ),
buffer_size( ( 2 * std::max( 65536, dictionary_size_ ) ) +
max_num_trials + after_size ),
buffer( new( std::nothrow ) uint8_t[buffer_size] ),
pos( 0 ),
cyclic_pos( 0 ),
stream_pos( 0 ),
pos_limit( buffer_size - after_size ),
match_len_limit_( len_limit ),
prev_positions( new( std::nothrow ) int32_t[num_prev_positions] ),
at_stream_end_( false )
{
prev_pos_tree = new( std::nothrow ) int32_t[2*dictionary_size_];
if( !buffer || !prev_positions || !prev_pos_tree )
{
if( prev_pos_tree ) delete[] prev_pos_tree;
if( prev_positions ) delete[] prev_positions;
if( buffer ) delete[] buffer;
throw std::bad_alloc();
}
for( int i = 0; i < num_prev_positions; ++i ) prev_positions[i] = -1;
}
Matchfinder( const int dict_size, const int len_limit );
~Matchfinder()
{ delete[] prev_pos_tree; delete[] prev_positions; delete[] buffer; }
@ -201,8 +176,9 @@ public:
int available_bytes() const throw() { return stream_pos - pos; }
long long data_position() const throw() { return partial_data_pos + pos; }
int dictionary_size() const throw() { return dictionary_size_; }
void finish() throw() { at_stream_end_ = true; }
void flushing( const bool b ) throw() { at_stream_end_ = b; }
bool finished() const throw() { return at_stream_end_ && pos >= stream_pos; }
int free_bytes() const throw() { return buffer_size - stream_pos; }
int match_len_limit() const throw() { return match_len_limit_; }
const uint8_t * ptr_to_current_pos() const throw() { return buffer + pos; }
@ -215,6 +191,12 @@ public:
return true;
}
bool enough_available_bytes() const throw()
{
return ( stream_pos > pos &&
( at_stream_end_ || stream_pos - pos >= after_size ) );
}
int true_match_len( const int index, const int distance, int len_limit ) const throw()
{
if( index + len_limit > available_bytes() )
@ -226,7 +208,7 @@ public:
}
int write_data( uint8_t * const in_buffer, const int in_size ) throw();
bool reset() throw();
void reset() throw();
bool move_pos() throw();
int longest_match_len( int * const distances = 0 ) throw();
};
@ -234,6 +216,7 @@ public:
class Range_encoder : public Circular_buffer
{
enum { min_free_bytes = 2 * max_num_trials };
uint64_t low;
long long partial_member_pos;
uint32_t range;
@ -256,13 +239,16 @@ class Range_encoder : public Circular_buffer
public:
Range_encoder()
:
Circular_buffer( 65536 + (2 * max_num_trials) ),
Circular_buffer( 65536 + min_free_bytes ),
low( 0 ),
partial_member_pos( 0 ),
range( 0xFFFFFFFF ),
ff_count( 0 ),
cache( 0 ) {}
bool enough_free_bytes() const throw()
{ return free_bytes() >= min_free_bytes; }
int read_data( uint8_t * const out_buffer, const int out_size ) throw()
{
const int size = Circular_buffer::read_data( out_buffer, out_size );
@ -270,7 +256,14 @@ public:
return size;
}
void flush() { for( int i = 0; i < 5; ++i ) shift_low(); }
void flush()
{
for( int i = 0; i < 5; ++i ) shift_low();
low = 0;
range = 0xFFFFFFFF;
ff_count = 0;
cache = 0;
}
long long member_position() const throw()
{ return partial_member_pos + used_bytes() + ff_count; }
@ -309,7 +302,7 @@ public:
for( int i = num_bits; i > 0; --i, mask >>= 1 )
{
const int bit = ( symbol & mask );
encode_bit( bm[model-1], bit );
encode_bit( bm[model], bit );
model <<= 1;
if( bit ) model |= 1;
}
@ -321,7 +314,7 @@ public:
for( int i = num_bits; i > 0; --i )
{
const int bit = symbol & 1;
encode_bit( bm[model-1], bit );
encode_bit( bm[model], bit );
model = ( model << 1 ) | bit;
symbol >>= 1;
}
@ -334,14 +327,14 @@ public:
{
const int bit = ( symbol >> i ) & 1;
const int match_bit = ( match_byte >> i ) & 1;
encode_bit( bm[(match_bit<<8)+model+0xFF], bit );
encode_bit( bm[(match_bit<<8)+model+0x100], bit );
model = ( model << 1 ) | bit;
if( match_bit != bit )
{
while( --i >= 0 )
{
const int bit = ( symbol >> i ) & 1;
encode_bit( bm[model-1], bit );
encode_bit( bm[model], bit );
model = ( model << 1 ) | bit;
}
break;
@ -421,6 +414,7 @@ class LZ_encoder
{
enum { dis_align_mask = dis_align_size - 1,
infinite_price = 0x0FFFFFFF,
max_marker_size = 15,
num_rep_distances = 4 }; // must be 4
struct Trial
@ -589,19 +583,18 @@ class LZ_encoder
int best_pair_sequence( const int reps[num_rep_distances],
const State & state );
void flush( const State & state );
bool full_flush();
public:
LZ_encoder( Matchfinder & mf, const File_header & header,
const long long member_size );
bool encode_member();
void finish_member()
{ if( !member_finished_ ) { flush( state ); member_finished_ = true; } }
bool encode_member( const bool finish );
bool member_finished() const throw()
{ return member_finished_ && !range_encoder.used_bytes(); }
int read_data( uint8_t * const buffer, const int size ) throw()
{ return range_encoder.read_data( buffer, size ); }
bool sync_flush();
long long member_position() const throw()
{ return range_encoder.member_position(); }