/*
* model_1e.c * * Un modelo probabilístico de orden 1, inicialmente vacío, con * exclusión de símbolos. * * Referencias: * * model_0.c * model_0s.c * model_1s.c * model_1e.c * Witten, Neal, and Cleary, CACM, 1987. * M. Nelson and J.-L. Gailly, The Data Compression Book. 1995. */ #include <stdio.h> #include "vlc.h" #include "codec.h" #include "model_1e.h" #include "model_0/find_symbols_and_indexes.h" void compute_cumulative_probs(unsigned short *prob, unsigned short *cum_prob) { int i; int cum = 0; for(i=ALPHA_SIZE; i>=0; i--) { cum_prob[i] = cum; cum += prob[i]; } } #define _symbol_to_index _symbol_to_index[context] #define _index_to_symbol _index_to_symbol[context] #define prob prob[context] #define cum_prob cum_prob[context] #include "model_1e/scale_probs.h" #include "model_0/increment_prob_of_index.h" #include "model_0/test_if_scale.h" #include "model_0/update_model.h" #undef _index_to_symbol #undef _symbol_to_index #undef cum_prob #undef prob #include "model_1e/init_model.h" #include "model_0/finish_model.h" /* Tiene en cuenta los símbolos que han aparecido en "context" para calcular las probabilidades acumuladas en el contexto "ESC". */ void exclude_symbols(int context, unsigned short *cum_prob) { unsigned short new_prob[ALPHA_SIZE+1]; int i; for(i=0; i<ALPHA_SIZE+1; i++) { new_prob[i] = prob[ESC][i]; if(prob[context][i]) { new_prob[i] = 0; } } compute_cumulative_probs(new_prob, cum_prob); } void encode_stream() { context = ESC; init_model(); init_encoder(); for(;;) { symbol = getchar(); if (symbol==EOF) break; index = find_index(symbol); if(prob[context][index]) { encode(index, cum_prob[context]); } else { unsigned short new_cum_prob[ALPHA_SIZE+1]; encode(ESC_index, cum_prob[context]); index = find_index(symbol); /* Calculamos un nuevo espacio de probabilidades, sabiendo que ninguno de los símbolos contemplados por el el contexto "context" es el símbolo a codificar "symbol". De esta forma, incrementamos la probabilidad del símbolo codificado. */ exclude_symbols(context, new_cum_prob); encode(index, new_cum_prob); } update_model(); context = symbol; } encode(EOS_index, cum_prob[context]); finish_encoder(); finish_model(); } void decode_stream() { context = ESC; init_model(); init_decoder(); for(;;) { index = decode(cum_prob[context]); if(index==EOS_index) break; symbol = find_symbol(index); if(symbol==ESC) { unsigned short new_cum_prob[ALPHA_SIZE+1]; exclude_symbols(context, new_cum_prob); index = decode(new_cum_prob); symbol = find_symbol(index); } putchar(symbol); update_model(); context = symbol; } finish_decoder(); finish_model(); } |