int encode_symbol(unsigned symbol, unsigned oldch) { long range; unsigned i; unsigned cum; unsigned prev_cum; unsigned char *freq_ptr; int current_pair; unsigned char high_half; unsigned high_half_weight; unsigned total_pair_weight; unsigned total_freq; FrequencyInfo *temp_freq_info; temp_freq_info = frequency_info[oldch]; freq_ptr = temp_freq_info->freq; total_freq = temp_freq_info->total_freq; prev_cum = 0; for (i = 0; i < symbol/2; i ++) { current_pair = *(freq_ptr++); total_pair_weight = both_weights[current_pair]; prev_cum += total_pair_weight; } if (symbol % 2 == 0) /* if even, prev cum is ok, update cum */ { current_pair = *freq_ptr; high_half = (unsigned char)((current_pair & HIGH_MASK) >> HIGH_SHIFT); high_half_weight = translate[high_half]; cum = prev_cum + high_half_weight; } else /* if odd, update both */ { current_pair = *freq_ptr; total_pair_weight = both_weights[current_pair]; cum = prev_cum + total_pair_weight; high_half = (unsigned char)((current_pair & HIGH_MASK) >> HIGH_SHIFT); high_half_weight = translate[high_half]; prev_cum += high_half_weight; } /* end updating */ range = (long)(high-low)+1; high = low + (unsigned)((range * cum)/total_freq-1); low = low + (unsigned)((range * prev_cum)/total_freq); for (;;) { if (high < HALF) bit_plus_follow_0 else if (low >= HALF) { bit_plus_follow_1 low -= (unsigned)HALF; high -= (unsigned)HALF; } else if (low >= FIRST_QTR && high < THIRD_QTR) { bits_to_follow ++; low -= (unsigned)FIRST_QTR; high -= (unsigned)FIRST_QTR; } else break; low <<= 1; high <<= 1; high ++; } /* end of bit output loop */ return 0; }