/** @brief After a character is decoded this is called to remove it from * the input. * @param symbol Symbol decoded */ static void arith_code_remove_symbol (arith_code_symbol_t *symbol) { int32_t range; // expand the range to account for removal range = (int32_t)(high - low) + 1; high = low + (uint16_t)((range * symbol->high_count) / symbol->scale - 1); low = low + (uint16_t)((range * symbol->low_count) / symbol->scale); for (;;) { if ((high & 0x8000) == (low & 0x8000)) { // if msdigits match, bits will be shifted out below } else if ((low & 0x4000) == 0x4000 && (high & 0x4000) == 0) { //underflow is looming shift out the 2nd msdigit code ^= 0x4000; low &= 0x3fff; high |= 0x4000; } else { // nothing can be shifted out, return return; } low <<= 1; high <<= 1; high |= 1; code <<= 1; code += input_bit (); } }
static int decode_symbol( int cum_freq[] ) { long range; /* Size of current code region */ int cum; /* Cumulative frequency calculated */ int symbol; /* Symbol decoded */ range = (long)(high-low)+1; cum = (int) /* Find cum freq for value. */ ((((long)(value-low)+1)*cum_freq[0]-1)/range); for (symbol = 1; cum_freq[symbol]>cum; symbol++) ; /* Then find symbol. */ high = low + /* Narrow the code region */ (range*cum_freq[symbol-1])/cum_freq[0]-1; /* to that allotted to this */ low = low + /* symbol. */ (range*cum_freq[symbol])/cum_freq[0]; for (;;) { /* Loop to get rid of bits. */ if (high<Half) { /* nothing */ /* Expand low half. */ } else if (low>=Half) { /* Expand high half. */ value -= Half; low -= Half; /* Subtract offset to top. */ high -= Half; } else if (low>=First_qtr /* Expand middle half. */ && high<Third_qtr) { value -= First_qtr; low -= First_qtr; /* Subtract offset to middle*/ high -= First_qtr; } else break; /* Otherwise exit loop. */ low = 2*low; high = 2*high+1; /* Scale up code range. */ value = 2*value+input_bit(); /* Move in next input bit. */ } return symbol; }
static void start_decoding( void ) { int i; value = 0; /* Input bits to fill the */ for (i = 1; i<=Code_value_bits; i++) { /* code value. */ value = 2*value+input_bit(); } low = 0; /* Full code range. */ high = Top_value; }
void Compression::start_decoding() { int i; VALUE = 0; ZEND = 0; ZATE = 1; for (i = 1; i <= Code_value_bits; i++) { /* code value. */ VALUE = 2 * VALUE + input_bit(); /* Move in next input bit. */ } }
/** @brief Initialize the decoding variables and read in 16 bits from input. */ static void arith_code_decode_init () { uint8_t i; code = 0; for (i = 0; i < 16; i++) { code <<= 1; code += input_bit (); } low = 0; high = 0xffff; }
/* * This routine is called to initialize the state of the arithmetic * decoder. This involves initializing the high and low registers * to their conventional starting values, plus reading the first * 16 bits from the input stream into the code value. */ void initialize_arithmetic_decoder( FILE *stream ) { int i; code = 0; for ( i = 0 ; i < 16 ; i++ ) { code <<= 1; code += input_bit( stream ); } low = 0; high = 0xffff; }
/* DECODE THE NEXT SYMBOL. */ int Compression::decode_symbol(bij_2c ff) { code_value range; /* Size of current code region */ int symbol; /* Symbol decoded */ int s1; range = (code_value) (high - low) + 1; /* YEAH NO +1 */ range = range / ff.Ftot; range = range * ff.Fone; range = high - range; if (VALUE >= range) { symbol = 1; low = range; } else { symbol = 0; high = range - 1; } ZATE = ((high < Half) || (low >= Half)) ? 1 : 0; s1 = 0; for (;;) { /* Loop to get rid of bits. */ if (high < Half) { /* nothing *//* Expand low half. */ } else if (low >= Half) { /* Expand high half. */ Zero_av = 0; VALUE -= Half; low -= Half; /* Subtract offset to top. */ high -= Half; } else if (low >= First_qtr /* Expand middle half. */ && high < Third_qtr) { Zero_av = 0; VALUE -= First_qtr; low -= First_qtr; /* Subtract offset to middle */ high -= First_qtr; } else break; /* Otherwise exit loop. */ low = 2 * low; high = 2 * high + 1; /* Scale up code range. */ s1 = 1; VALUE = 2 * VALUE + input_bit(); /* Move in next input bit. */ } if (ZATE == 1) { if (low == 0 && Zero_av == 0) Zero_av = 1; /* only first time */ else if (low > 0) Zero_av = 0; /* available in future */ else Zero_av = 2; /* not available */ } else if (s1 == 1) Zero_av = 0; return symbol; }
/* * Just figuring out what the present symbol is doesn't remove * it from the input bit stream. After the character has been * decoded, this routine has to be called to remove it from the * input stream. */ void remove_symbol_from_stream( FILE *stream, SYMBOL *s ) { long range; /* * First, the range is expanded to account for the symbol removal. */ range = (long)( high - low ) + 1; high = low + (unsigned short int) (( range * s->high_count ) / s->scale - 1 ); low = low + (unsigned short int) (( range * s->low_count ) / s->scale ); /* * Next, any possible bits are shipped out. */ for ( ; ; ) { /* * If the MSDigits match, the bits will be shifted out. */ if ( ( high & 0x8000 ) == ( low & 0x8000 ) ) { } /* * Else, if underflow is threatining, shift out the 2nd MSDigit. */ else if ((low & 0x4000) == 0x4000 && (high & 0x4000) == 0 ) { code ^= 0x4000; low &= 0x3fff; high |= 0x4000; } /* * Otherwise, nothing can be shifted out, so I return. */ else return; low <<= 1; high <<= 1; high |= 1; code <<= 1; code += input_bit( stream ); } }
/* * Just figuring out what the present symbol is doesn't remove * it from the input bit stream. After the character has been * decoded, this routine has to be called to remove it from the * input stream. */ void remove_symbol_from_stream( FILE *stream, SYMBOL *s ) { unsigned long long range; range = (unsigned long long) ( high-low ) + 1; high = SafeConvert(div128(mult128(range, s->high_count), s->scale).lo + low - 1); low = SafeConvert(div128(mult128(range, s->low_count), s->scale).lo + low); /* * Next, any possible bits are shipped out. */ for ( ; ; ) { /* * If the MSDigits match, the bits will be shifted out. */ if ( ( high & LAST_BIT ) == ( low & LAST_BIT ) ) { } /* * Else, if underflow is threatining, shift out the 2nd MSDigit. */ else if ((low & NEXT_TO_LAST_BIT) == NEXT_TO_LAST_BIT && (high & NEXT_TO_LAST_BIT) == 0 ) { code ^= NEXT_TO_LAST_BIT; low &= NEXT_TO_LAST_BIT_MINUS_ONE; high |= NEXT_TO_LAST_BIT; } /* * Otherwise, nothing can be shifted out, so I return. */ else return; low <<= 1; high <<= 1; high |= 1; code <<= 1; code += input_bit( stream ); } }