diff options
Diffstat (limited to '')
-rw-r--r-- | decoder.h | 191 |
1 files changed, 84 insertions, 107 deletions
@@ -15,182 +15,159 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -enum { Ib_buffer_size = 65536 }; +enum { Rd_buffer_size = 16384 }; -struct Input_buffer +struct Range_decoder { - uint8_t * buffer; + long long partial_member_pos; + uint8_t * buffer; // input buffer int pos; int stream_pos; // when reached, a new block must be read + uint32_t code; + uint32_t range; int infd_; // input file descriptor bool at_stream_end; }; -bool Ib_read_block( struct Input_buffer * const ibuf ); +bool Rd_read_block( struct Range_decoder * const rdec ); -static inline void Ib_init( struct Input_buffer * const ibuf, const int infd ) +static inline void Rd_init( struct Range_decoder * const rdec, const int infd ) { - ibuf->buffer = (uint8_t *)malloc( Ib_buffer_size ); - if( !ibuf->buffer ) + rdec->partial_member_pos = 0; + rdec->buffer = (uint8_t *)malloc( Rd_buffer_size ); + if( !rdec->buffer ) { show_error( "not enough memory. Find a machine with more memory", 0, false ); cleanup_and_fail( 1 ); } - ibuf->pos = 0; - ibuf->stream_pos = 0; - ibuf->infd_ = infd; - ibuf->at_stream_end = false; + rdec->pos = 0; + rdec->stream_pos = 0; + rdec->code = 0; + rdec->range = 0xFFFFFFFF; + rdec->infd_ = infd; + rdec->at_stream_end = false; } -static inline void Ib_free( struct Input_buffer * const ibuf ) - { free( ibuf->buffer ); ibuf->buffer = 0; } +static inline void Rd_free( struct Range_decoder * const rdec ) + { free( rdec->buffer ); rdec->buffer = 0; } -static inline bool Ib_finished( struct Input_buffer * const ibuf ) - { return ibuf->at_stream_end && ibuf->pos >= ibuf->stream_pos; } +static inline bool Rd_code_is_zero( struct Range_decoder * const rdec ) + { return ( rdec->code == 0 ); } -static inline uint8_t Ib_get_byte( struct Input_buffer * const ibuf ) - { - if( ibuf->pos >= ibuf->stream_pos && !Ib_read_block( ibuf ) ) - return 0; - return ibuf->buffer[ibuf->pos++]; - } +static inline bool Rd_finished( struct Range_decoder * const rdec ) + { return rdec->at_stream_end && rdec->pos >= rdec->stream_pos; } +static inline long long Rd_member_position( struct Range_decoder * const rdec ) + { return rdec->partial_member_pos + rdec->pos; } -struct Range_decoder - { - long long member_pos; - uint32_t code; - uint32_t range; - struct Input_buffer * ibuf; - }; +static inline void Rd_reset_member_position( struct Range_decoder * const rdec ) + { rdec->partial_member_pos = -rdec->pos; } -static inline uint8_t Rd_get_byte( struct Range_decoder * const range_decoder ) +static inline uint8_t Rd_get_byte( struct Range_decoder * const rdec ) { - ++range_decoder->member_pos; - return Ib_get_byte( range_decoder->ibuf ); + if( rdec->pos >= rdec->stream_pos && !Rd_read_block( rdec ) ) return 0; + return rdec->buffer[rdec->pos++]; } -static inline void Rd_init( struct Range_decoder * const range_decoder, - struct Input_buffer * const buf ) +static inline void Rd_load( struct Range_decoder * const rdec ) { - range_decoder->member_pos = sizeof (File_header); - range_decoder->code = 0; - range_decoder->range = 0xFFFFFFFF; - range_decoder->ibuf = buf; + rdec->code = 0; + rdec->range = 0xFFFFFFFFU; for( int i = 0; i < 5; ++i ) - range_decoder->code = (range_decoder->code << 8) | - Rd_get_byte( range_decoder ); + rdec->code = (rdec->code << 8) | Rd_get_byte( rdec ); } -static inline bool Rd_code_is_zero( struct Range_decoder * const range_decoder ) - { return ( range_decoder->code == 0 ); } -static inline bool Rd_finished( struct Range_decoder * const range_decoder ) - { return Ib_finished( range_decoder->ibuf ); } -static inline long long Rd_member_position( struct Range_decoder * const range_decoder ) - { return range_decoder->member_pos; } - -static inline void Rd_reload( struct Range_decoder * const range_decoder ) +static inline void Rd_normalize( struct Range_decoder * const rdec ) { - range_decoder->code = 0; - range_decoder->range = 0xFFFFFFFF; - for( int i = 0; i < 5; ++i ) - range_decoder->code = (range_decoder->code << 8) | - Rd_get_byte( range_decoder ); - } - -static inline void Rd_normalize( struct Range_decoder * const range_decoder ) - { - if( range_decoder->range <= 0x00FFFFFF ) + if( rdec->range <= 0x00FFFFFFU ) { - range_decoder->range <<= 8; - range_decoder->code = (range_decoder->code << 8) | - Rd_get_byte( range_decoder ); + rdec->range <<= 8; + rdec->code = (rdec->code << 8) | Rd_get_byte( rdec ); } } -static inline int Rd_decode( struct Range_decoder * const range_decoder, +static inline int Rd_decode( struct Range_decoder * const rdec, const int num_bits ) { int symbol = 0; for( int i = num_bits; i > 0; --i ) { symbol <<= 1; - if( range_decoder->range <= 0x00FFFFFF ) + if( rdec->range <= 0x00FFFFFFU ) { - range_decoder->range <<= 7; - range_decoder->code = (range_decoder->code << 8) | - Rd_get_byte( range_decoder ); - if( range_decoder->code >= range_decoder->range ) - { range_decoder->code -= range_decoder->range; symbol |= 1; } + rdec->range <<= 7; + rdec->code = (rdec->code << 8) | Rd_get_byte( rdec ); + if( rdec->code >= rdec->range ) + { rdec->code -= rdec->range; symbol |= 1; } } else { - range_decoder->range >>= 1; - if( range_decoder->code >= range_decoder->range ) - { range_decoder->code -= range_decoder->range; symbol |= 1; } + rdec->range >>= 1; + if( rdec->code >= rdec->range ) + { rdec->code -= rdec->range; symbol |= 1; } } } return symbol; } -static inline int Rd_decode_bit( struct Range_decoder * const range_decoder, +static inline int Rd_decode_bit( struct Range_decoder * const rdec, Bit_model * const probability ) { - Rd_normalize( range_decoder ); - const uint32_t bound = ( range_decoder->range >> bit_model_total_bits ) * + Rd_normalize( rdec ); + const uint32_t bound = ( rdec->range >> bit_model_total_bits ) * *probability; - if( range_decoder->code < bound ) + if( rdec->code < bound ) { - range_decoder->range = bound; + rdec->range = bound; *probability += (bit_model_total - *probability) >> bit_model_move_bits; return 0; } else { - range_decoder->range -= bound; - range_decoder->code -= bound; + rdec->range -= bound; + rdec->code -= bound; *probability -= *probability >> bit_model_move_bits; return 1; } } -static inline int Rd_decode_tree( struct Range_decoder * const range_decoder, +static inline int Rd_decode_tree( struct Range_decoder * const rdec, Bit_model bm[], const int num_bits ) { int model = 1; for( int i = num_bits; i > 0; --i ) - model = ( model << 1 ) | Rd_decode_bit( range_decoder, &bm[model] ); + model = ( model << 1 ) | Rd_decode_bit( rdec, &bm[model] ); return model - (1 << num_bits); } -static inline int Rd_decode_tree_reversed( struct Range_decoder * const range_decoder, +static inline int Rd_decode_tree_reversed( struct Range_decoder * const rdec, Bit_model bm[], const int num_bits ) { int model = 1; int symbol = 0; for( int i = 0; i < num_bits; ++i ) { - const int bit = Rd_decode_bit( range_decoder, &bm[model] ); + const int bit = Rd_decode_bit( rdec, &bm[model] ); model <<= 1; if( bit ) { model |= 1; symbol |= (1 << i); } } return symbol; } -static inline int Rd_decode_matched( struct Range_decoder * const range_decoder, +static inline int Rd_decode_matched( struct Range_decoder * const rdec, Bit_model bm[], const int match_byte ) { - Bit_model *bm1 = bm + 0x100; + Bit_model * const bm1 = bm + 0x100; int symbol = 1; - for( int i = 1; i <= 8; ++i ) + for( int i = 7; i >= 0; --i ) { - const int match_bit = ( match_byte << i ) & 0x100; - const int bit = Rd_decode_bit( range_decoder, &bm1[match_bit+symbol] ); + const int match_bit = ( match_byte >> i ) & 1; + const int bit = Rd_decode_bit( rdec, &bm1[(match_bit<<8)+symbol] ); symbol = ( symbol << 1 ) | bit; - if( ( match_bit && !bit ) || ( !match_bit && bit ) ) + if( match_bit != bit ) { - while( ++i <= 8 ) - symbol = ( symbol << 1 ) | Rd_decode_bit( range_decoder, &bm[symbol] ); + while( --i >= 0 ) + symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] ); break; } } @@ -222,18 +199,16 @@ static inline void Led_init( struct Len_decoder * const len_decoder ) } static inline int Led_decode( struct Len_decoder * const len_decoder, - struct Range_decoder * const range_decoder, + struct Range_decoder * const rdec, const int pos_state ) { - if( Rd_decode_bit( range_decoder, &len_decoder->choice1 ) == 0 ) - return Rd_decode_tree( range_decoder, len_decoder->bm_low[pos_state], - len_low_bits ); - if( Rd_decode_bit( range_decoder, &len_decoder->choice2 ) == 0 ) + if( Rd_decode_bit( rdec, &len_decoder->choice1 ) == 0 ) + return Rd_decode_tree( rdec, len_decoder->bm_low[pos_state], len_low_bits ); + if( Rd_decode_bit( rdec, &len_decoder->choice2 ) == 0 ) return len_low_symbols + - Rd_decode_tree( range_decoder, len_decoder->bm_mid[pos_state], - len_mid_bits ); + Rd_decode_tree( rdec, len_decoder->bm_mid[pos_state], len_mid_bits ); return len_low_symbols + len_mid_symbols + - Rd_decode_tree( range_decoder, len_decoder->bm_high, len_high_bits ); + Rd_decode_tree( rdec, len_decoder->bm_high, len_high_bits ); } @@ -253,15 +228,15 @@ static inline int Lid_state( const int prev_byte ) { return ( prev_byte >> ( 8 - literal_context_bits ) ); } static inline uint8_t Lid_decode( struct Literal_decoder * const literal_decoder, - struct Range_decoder * const range_decoder, + struct Range_decoder * const rdec, const uint8_t prev_byte ) - { return Rd_decode_tree( range_decoder, literal_decoder->bm_literal[Lid_state(prev_byte)], 8 ); } + { return Rd_decode_tree( rdec, literal_decoder->bm_literal[Lid_state(prev_byte)], 8 ); } static inline uint8_t Lid_decode_matched( struct Literal_decoder * const literal_decoder, - struct Range_decoder * const range_decoder, + struct Range_decoder * const rdec, const uint8_t prev_byte, const uint8_t match_byte ) - { return Rd_decode_matched( range_decoder, literal_decoder->bm_literal[Lid_state(prev_byte)], match_byte ); } + { return Rd_decode_matched( rdec, literal_decoder->bm_literal[Lid_state(prev_byte)], match_byte ); } struct LZ_decoder @@ -286,7 +261,7 @@ struct LZ_decoder Bit_model bm_dis[modeled_distances-end_dis_model]; Bit_model bm_align[dis_align_size]; - struct Range_decoder range_decoder; + struct Range_decoder * range_decoder; struct Len_decoder len_decoder; struct Len_decoder rep_match_len_decoder; struct Literal_decoder literal_decoder; @@ -335,7 +310,7 @@ bool LZd_verify_trailer( struct LZ_decoder * const decoder, static inline void LZd_init( struct LZ_decoder * const decoder, const File_header header, - struct Input_buffer * const ibuf, const int outfd ) + struct Range_decoder * const rdec, const int outfd ) { decoder->partial_data_pos = 0; decoder->format_version = Fh_version( header ); @@ -349,7 +324,7 @@ static inline void LZd_init( struct LZ_decoder * const decoder, } decoder->pos = 0; decoder->stream_pos = 0; - decoder->crc_ = 0xFFFFFFFF; + decoder->crc_ = 0xFFFFFFFFU; decoder->outfd_ = outfd; for( int i = 0; i < St_states; ++i ) @@ -372,7 +347,7 @@ static inline void LZd_init( struct LZ_decoder * const decoder, for( int i = 0; i < dis_align_size; ++i ) Bm_init( &decoder->bm_align[i] ); - Rd_init( &decoder->range_decoder, ibuf ); + decoder->range_decoder = rdec; Led_init( &decoder->len_decoder ); Led_init( &decoder->rep_match_len_decoder ); Lid_init( &decoder->literal_decoder ); @@ -383,11 +358,13 @@ static inline void LZd_free( struct LZ_decoder * const decoder ) { free( decoder->buffer ); decoder->buffer = 0; } static inline uint32_t LZd_crc( struct LZ_decoder * const decoder ) - { return decoder->crc_ ^ 0xFFFFFFFF; } + { return decoder->crc_ ^ 0xFFFFFFFFU; } + int LZd_decode_member( struct LZ_decoder * const decoder, struct Pretty_print * const pp ); static inline long long LZd_member_position( struct LZ_decoder * const decoder ) - { return Rd_member_position( &decoder->range_decoder ); } + { return Rd_member_position( decoder->range_decoder ); } + static inline long long LZd_data_position( struct LZ_decoder * const decoder ) { return decoder->partial_data_pos + decoder->pos; } |