update_model(int symbol,unsigned char oldch) { int i; int index; unsigned char *freq_ptr; unsigned char freq; int old_weight_code; unsigned weight_gain; unsigned char temp_freq; long temp_total_freq; FrequencyInfo *temp_freq_info; unsigned char low_symbol; low_symbol = (unsigned char)(symbol_translation[symbol] & 255); char_total = (unsigned char)(char_total + low_symbol); old_weight_code = -1; temp_freq_info = frequency_info[oldch]; freq_ptr = temp_freq_info->freq; index = symbol/2; if (symbol % 2 == 0) /* if a high symbol */ { temp_freq = (unsigned char)((freq_ptr[index] & HIGH_MASK) >> HIGH_SHIFT); if (temp_freq == 0) { freq_ptr[index] += INIT_INDEX << HIGH_SHIFT; temp_freq_info->total_freq += translate[INIT_INDEX] - translate[0]; } else if (char_total > upgrade_threshold[temp_freq]) { old_weight_code = temp_freq; freq_ptr[index] += HIGH_INCREMENT; /* bump it */ } } else /* if a low one */ { temp_freq = (unsigned char)((freq_ptr[index] & LOW_MASK) >> LOW_SHIFT); if (temp_freq == 0) { freq_ptr[index] += INIT_INDEX << LOW_SHIFT; temp_freq_info->total_freq += translate[INIT_INDEX] - translate[0]; } else if (char_total > upgrade_threshold[temp_freq]) { old_weight_code = temp_freq; freq_ptr[index] += LOW_INCREMENT; /* bump it */ } } if (old_weight_code != -1) /* if there was an adjustment of weight */ { weight_gain = translate[old_weight_code+1] - translate[old_weight_code]; temp_freq_info->total_freq += weight_gain; } temp_total_freq = temp_freq_info->total_freq; while (temp_total_freq > MAX_FREQUENCY) { temp_total_freq = 0; freq_ptr = temp_freq_info->freq; for (i = 0; i < (NO_OF_SYMBOLS+1)/2; i ++) { if (*freq_ptr == 0) /* if this is at the bottom, forget it */ temp_total_freq += BOTH_WEIGHTS_ZERO; else /* if it needs to be updated */ { freq = *freq_ptr; if ((freq & HIGH_MASK) != 0) { /* if the top is not at the lowest value*/ *freq_ptr -= HIGH_INCREMENT; /* decrement it */ } if ((freq & LOW_MASK) != 0) { /* if the low is not at the lowest value*/ *freq_ptr -= LOW_INCREMENT; /* decrement it */ } temp_total_freq += both_weights[*freq_ptr]; } freq_ptr ++; } } temp_freq_info->total_freq = (unsigned)temp_total_freq; return(0); }