|
|
/*
* dectree.c * * Decoding the encoded tree structures * * To save much code size, the fillbuf()/getbits() calls have * been made into functions, rather than being inlined macros. * The macros actually take up a lot of space. There is no * performance loss from doing so here. */ #include "decoder.h"
/* number of elements in pre-tree */ #define NUM_DECODE_SMALL 20
/* lookup table size */ #define DS_TABLE_BITS 8
/* macro to decode a pre-tree element */ #define DECODE_SMALL(item) \
{ \ item = small_table[context->dec_bitbuf >> (32-DS_TABLE_BITS) ]; \ if (item < 0) \ { \ mask = (1L << (32-1-DS_TABLE_BITS)); \ do \ { \ item = -item; \ if (context->dec_bitbuf & mask) \ item = leftright_s[2*item+1]; \ else \ item = leftright_s[2*item]; \ mask >>= 1; \ } while (item < 0); \ } \ fillbuf(context, small_bitlen[item]); \ }
/*
* Reads a compressed tree structure */ static bool NEAR ReadRepTree( t_decoder_context *context, int num_elements, byte *lastlen, byte *len ) { ulong mask; int i; int consecutive; byte small_bitlen[24]; short small_table[1 << DS_TABLE_BITS]; short leftright_s [2*(2 * 24 - 1)]; short Temp;
/* Declare this inline to help compilers see the optimisation */ static const byte Modulo17Lookup[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
/* read pre-tree */ for (i = 0; i < NUM_DECODE_SMALL; i++) { small_bitlen[i] = (byte) getbits(context, 4); }
/* exceeded input buffer? */ if (context->dec_error_condition) return false;
/* make a table for this pre-tree */ make_table( context, NUM_DECODE_SMALL, small_bitlen, DS_TABLE_BITS, small_table, leftright_s );
for (i = 0; i < num_elements; i++) { DECODE_SMALL(Temp);
/* exceeded input buffer? */ if (context->dec_error_condition) return false;
/* Repeat "TREE_ENC_REP_MIN...TREE_ENC_REP_MIN+(1<<TREE_ENC_REPZ_FIRST_EXTRA_BITS)-1" zeroes */ if (Temp == 17) { /* code 17 means "a small number of repeated zeroes" */ consecutive = (byte) getbits(context, TREE_ENC_REPZ_FIRST_EXTRA_BITS); consecutive += TREE_ENC_REP_MIN;
/* boundary check */ if (i + consecutive >= num_elements) consecutive = num_elements-i;
while (consecutive-- > 0) len[i++] = 0;
i--; } else if (Temp == 18) { /* code 18 means "a large number of repeated zeroes" */
/* Repeat "TREE_ENC_REP_MIN+(1<<TREE_ENC_REPZ_FIRST_EXTRA_BITS)-1...<ditto>+(1<<TREE_ENC_REPZ_SECOND_EXTRA_BITS)-1" zeroes */ consecutive = (byte) getbits(context, TREE_ENC_REPZ_SECOND_EXTRA_BITS); consecutive += (TREE_ENC_REP_MIN+TREE_ENC_REP_ZERO_FIRST);
/* boundary check */ if (i + consecutive >= num_elements) consecutive = num_elements-i;
while (consecutive-- > 0) len[i++] = 0;
i--; } else if (Temp == 19) { byte value;
/* code 19 means "a small number of repeated somethings" */ /* Repeat "TREE_ENC_REP_MIN...TREE_ENC_REP_MIN+(1<<TREE_ENC_REP_SAME_EXTRA_BITS)-1" elements */ consecutive = (byte) getbits(context, TREE_ENC_REP_SAME_EXTRA_BITS); consecutive += TREE_ENC_REP_MIN;
/* boundary check */ if (i + consecutive >= num_elements) consecutive = num_elements-i;
/* get the element number to repeat */ DECODE_SMALL(Temp); value = Modulo17Lookup[(lastlen[i] - Temp)+17];
while (consecutive-- > 0) len[i++] = value;
i--; } else { len[i] = Modulo17Lookup[(lastlen[i] - Temp)+17]; } }
/* exceeded input buffer? */ if (context->dec_error_condition) return false; else return true; }
bool NEAR read_main_and_secondary_trees(t_decoder_context *context) { /* read first 256 elements (characters) of the main tree */ if (false == ReadRepTree( context, 256, context->dec_main_tree_prev_len, context->dec_main_tree_len)) { return false; }
/*
* read remaining elements (primary match lengths * positions) * of the main tree */ if (false == ReadRepTree( context, context->dec_num_position_slots*NUM_LENGTHS, &context->dec_main_tree_prev_len[256], &context->dec_main_tree_len[256])) { return false; }
/* create lookup table for the main tree */ if (false == make_table( context, MAIN_TREE_ELEMENTS, context->dec_main_tree_len, MAIN_TREE_TABLE_BITS, context->dec_main_tree_table, context->dec_main_tree_left_right)) { return false; }
/* read secondary length tree */ if (false == ReadRepTree( context, NUM_SECONDARY_LENGTHS, context->dec_secondary_length_tree_prev_len, context->dec_secondary_length_tree_len)) { return false; }
/* create lookup table for the secondary length tree */ if (false == make_table( context, NUM_SECONDARY_LENGTHS, context->dec_secondary_length_tree_len, SECONDARY_LEN_TREE_TABLE_BITS, context->dec_secondary_length_tree_table, context->dec_secondary_length_tree_left_right)) { return false; }
return true; }
/* read 8 element aligned offset tree */ bool NEAR read_aligned_offset_tree(t_decoder_context *context) { int i;
/* read bit lengths of the 8 codes */ for (i = 0; i < 8; i++) { context->dec_aligned_len[i] = (byte) getbits(context, 3); }
if (context->dec_error_condition) return false;
/*
* Make table with no left/right, and byte Table[] instead of * short Table[] */ if (false == make_table_8bit( context, context->dec_aligned_len, (byte *) context->dec_aligned_table)) { return false; }
return true; }
|