diff options
Diffstat (limited to 'decoder.h')
-rw-r--r-- | decoder.h | 51 |
1 files changed, 27 insertions, 24 deletions
@@ -19,12 +19,12 @@ class Range_decoder { enum { buffer_size = 16384 }; unsigned long long partial_member_pos; - uint8_t * const buffer; /* input buffer */ - int pos; /* current pos in buffer */ - int stream_pos; /* when reached, a new block must be read */ + uint8_t * const buffer; // input buffer + int pos; // current pos in buffer + int stream_pos; // when reached, a new block must be read uint32_t code; uint32_t range; - const int infd; /* input file descriptor */ + const int infd; // input file descriptor bool at_stream_end; bool read_block(); @@ -214,12 +214,11 @@ class LZ_decoder unsigned long long partial_data_pos; Range_decoder & rdec; const unsigned dictionary_size; - const int buffer_size; - uint8_t * const buffer; /* output buffer */ - int pos; /* current pos in buffer */ - int stream_pos; /* first byte not yet written to file */ + uint8_t * const buffer; // output buffer + unsigned pos; // current pos in buffer + unsigned stream_pos; // first byte not yet written to file uint32_t crc_; - const int outfd; /* output file descriptor */ + const int outfd; // output file descriptor unsigned long long stream_position() const { return partial_data_pos + stream_pos; } @@ -228,37 +227,42 @@ class LZ_decoder uint8_t peek_prev() const { - const int i = ( ( pos > 0 ) ? pos : buffer_size ) - 1; + const unsigned i = ( ( pos > 0 ) ? pos : dictionary_size ) - 1; return buffer[i]; } - uint8_t peek( const int distance ) const + uint8_t peek( const unsigned distance ) const { - int i = pos - distance - 1; - if( i < 0 ) i += buffer_size; + unsigned i = pos - distance - 1; + if( pos <= distance ) i += dictionary_size; return buffer[i]; } void put_byte( const uint8_t b ) { buffer[pos] = b; - if( ++pos >= buffer_size ) flush_data(); + if( ++pos >= dictionary_size ) flush_data(); } - void copy_block( const int distance, int len ) + void copy_block( const unsigned distance, unsigned len ) { - int i = pos - distance - 1; - if( i < 0 ) i += buffer_size; - if( len < buffer_size - std::max( pos, i ) && len <= std::abs( pos - i ) ) + unsigned i = pos - distance - 1; + bool fast; + if( pos <= distance ) + { i += dictionary_size; + fast = ( len <= dictionary_size - i && len <= i - pos ); } + else + fast = ( len < dictionary_size - pos && len <= pos - i ); + if( fast ) // no wrap, no overlap { - std::memcpy( buffer + pos, buffer + i, len ); // no wrap, no overlap + std::memcpy( buffer + pos, buffer + i, len ); pos += len; } else for( ; len > 0; --len ) { buffer[pos] = buffer[i]; - if( ++pos >= buffer_size ) flush_data(); - if( ++i >= buffer_size ) i = 0; + if( ++pos >= dictionary_size ) flush_data(); + if( ++i >= dictionary_size ) i = 0; } } @@ -275,13 +279,12 @@ public: partial_data_pos( 0 ), rdec( rde ), dictionary_size( header.dictionary_size() ), - buffer_size( std::max( 65536U, dictionary_size ) ), - buffer( new uint8_t[buffer_size] ), + buffer( new uint8_t[dictionary_size] ), pos( 0 ), stream_pos( 0 ), crc_( 0xFFFFFFFFU ), outfd( ofd ) - { buffer[buffer_size-1] = 0; } // prev_byte of first byte + { buffer[dictionary_size-1] = 0; } // prev_byte of first byte ~LZ_decoder() { delete[] buffer; } |