diff options
Diffstat (limited to '')
-rw-r--r-- | decoder.h | 39 |
1 files changed, 21 insertions, 18 deletions
@@ -212,10 +212,9 @@ 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 + 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 member_version; @@ -225,37 +224,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; } } @@ -268,14 +272,13 @@ 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 ), member_version( header.version() ) - { buffer[buffer_size-1] = 0; } // prev_byte of first byte + { buffer[dictionary_size-1] = 0; } // prev_byte of first byte ~LZ_decoder() { delete[] buffer; } |