Главная страница

РГР_Слєпцова_ДА-62. Програмна реалізація методу


Скачать 145.82 Kb.
НазваниеПрограмна реалізація методу
Дата03.09.2018
Размер145.82 Kb.
Формат файлаdocx
Имя файлаРГР_Слєпцова_ДА-62.docx
ТипДокументы
#49682
страница4 из 4
1   2   3   4

//------------------------------------------------------------

// Обновление модели очередным символом

void update_model ( int Symbol)

{

int i;

int ch_i, ch_Symbol;

int cum;

// проверка на переполнение счетчика частоты

if (cum_freq [0] == MAX_FREQUENCY)

{

cum = 0;

// масштабирование частот при переполнении

for ( i = NO_OF_SymbolS; i >= 0; i--)

{

freq [i] = (freq [i] + 1) / 2;

cum_freq [i] = cum;

cum += freq [i];

}

}

for ( i = Symbol; freq [i] == freq [i - 1]; i--);

if (i < Symbol)

{

ch_i = index_to_char [i];

ch_Symbol = index_to_char [Symbol];

index_to_char [i] = ch_Symbol;

index_to_char [Symbol] = ch_i;

char_to_index [ch_i] = Symbol;

char_to_index [ch_Symbol] = i;

}

// обновление значений в таблицах частот

freq [i] += 1;

while (i > 0)

{

i -= 1;

cum_freq [i] += 1;

}

}

//------------------------------------------------------------

// Инициализация побитового ввода

void start_inputing_bits (void)

{

bits_to_go = 0;

garbage_bits = 0;

}

//------------------------------------------------------------

// Ввод бита

int input_bit (void)

{

int t;

if (bits_to_go == 0)

{

buffer = getc (in);

if (buffer == EOF)

{

garbage_bits += 1;

if (garbage_bits > BITS_IN_REGISTER - 2)

{

printf ("Ошибка в сжатом файле\n");



}

}

bits_to_go = 8;

}

t = buffer & 1;

buffer >>= 1;

bits_to_go -= 1;

return t;

}

//------------------------------------------------------------

// Инициализация побитового вывода

void start_outputing_bits (void)

{

buffer = 0;

bits_to_go = 8;

}

//------------------------------------------------------------

// Вывод бита

void output_bit ( int bit)

{

buffer >>= 1; // делим на два

if (bit)

buffer |= 0x80;

bits_to_go -= 1;

if (bits_to_go == 0)

{

putc ( buffer, out);

bits_to_go = 8;

}

}
//------------------------------------------------------------

// Очистка вывода

void done_outputing_bits (void)

{

putc ( buffer >> bits_to_go, out);

}
//------------------------------------------------------------

// Вывод бита

void output_bit_plus_follow ( int bit)

{

output_bit (bit);

while (bits_to_follow > 0)

{

output_bit (!bit);

bits_to_follow--;

}

}

//------------------------------------------------------------

// Инициализация границ

void start_encoding (void)

{

lowLimit = 0l;

highLimit = TOP_VALUE;

bits_to_follow = 0l;

}

//------------------------------------------------------------

// Очистка вывода

void done_encoding (void)

{

bits_to_follow++;

if (lowLimit < FIRST_QTR)

output_bit_plus_follow (0);

else

output_bit_plus_follow (1);

}
//------------------------------------------------------------

/* Инициализация регистров перед декодированием.

Загрузка начала сжатого сообщения

*/

void start_decoding (void)

{

int i;

value = 0l;

for ( i = 1; i <= BITS_IN_REGISTER; i++)

value = 2 * value + input_bit ();

lowLimit = 0l;

highLimit = TOP_VALUE;

}

//------------------------------------------------------------

// Кодирование символа

void encode_Symbol ( int Symbol)

{

long limit;

// пересчет значений границ

limit = (long) (highLimit - lowLimit) + 1;

highLimit = lowLimit + (limit * cum_freq [Symbol - 1]) / cum_freq [0] - 1;

lowLimit = lowLimit + (limit * cum_freq [Symbol]) / cum_freq [0];

// выдвигание очередных битов

for (;;)

{

if (highLimit < HALF)

output_bit_plus_follow (0);

else if (lowLimit >= HALF)

{

output_bit_plus_follow (1);

lowLimit -= HALF;

highLimit -= HALF;

}

else if (lowLimit >= FIRST_QTR && highLimit < THIRD_QTR)

{

bits_to_follow += 1;

lowLimit -= FIRST_QTR;

highLimit -= FIRST_QTR;

}

else

break;

// сдвиг влево с "втягиванием" очередного бита

lowLimit = 2 * lowLimit;

highLimit = 2 * highLimit + 1;

}

}

//------------------------------------------------------------

// Декодирование символа

int decode_Symbol (void)

{

long limit;

int cum, Symbol;

// определение текущего масштаба частот

limit = (long) (highLimit - lowLimit) + 1;

// масштабирование значения в регистре кода

cum = (int)

((((long) (value - lowLimit) + 1) * cum_freq [0] - 1) / limit);

// поиск соответствующего символа в таблице частот

for (Symbol = 1; cum_freq [Symbol] > cum; Symbol++);

// пересчет границ

highLimit = lowLimit + (limit * cum_freq [Symbol - 1]) / cum_freq [0] - 1;

lowLimit = lowLimit + (limit * cum_freq [Symbol]) / cum_freq [0];

// удаление очередного символа из входного потока

for (;;)

{

if (highLimit < HALF)

{

}

else if (lowLimit >= HALF)

{

value -= HALF;

lowLimit -= HALF;

highLimit -= HALF;

}

else if (lowLimit >= FIRST_QTR && highLimit < THIRD_QTR)

{

value -= FIRST_QTR;

lowLimit -= FIRST_QTR;

highLimit -= FIRST_QTR;

}

else

break;

// сдвиг влево

lowLimit = 2 * lowLimit;

highLimit = 2 * highLimit + 1;

value = 2 * value + input_bit ();

}

return Symbol;

}

//------------------------------------------------------------

// кодирование

void encode ( char *infile, char *outfile)

{

int ch, Symbol;
in = fopen ( infile, "r+b");

out = fopen ( outfile, "w+b");

if (in == NULL || out == NULL)

return;

start_model ();

start_outputing_bits ();

start_encoding ();

for (;;)

{

ch = getc (in);

if (ch == EOF)

break;

Symbol = char_to_index [ch];

encode_Symbol (Symbol);

update_model (Symbol);

}

encode_Symbol (EOF_Symbol);

done_encoding ();

done_outputing_bits ();

fclose (in);

fclose (out);

}

//------------------------------------------------------------

// декодирование

void decode ( char *infile, char *outfile)

{

int ch, Symbol;
in = fopen ( infile, "r+b");

out = fopen ( outfile, "w+b");

if (in == NULL || out == NULL)

return;

start_model ();

start_inputing_bits ();

start_decoding ();

for (;;)

{

Symbol = decode_Symbol ();

if (Symbol == EOF_Symbol)

break;

ch = index_to_char [Symbol];

putc ( ch, out);

update_model (Symbol);

}

fclose (in);

fclose (out);

}

int main (int argc, char** argv)

{

encode ( "test.txt", "2.txt");

decode ( "2.txt", "3.txt");

return 0;

}
1   2   3   4


написать администратору сайта