Рефераты. Алгоритмы сжатия данных

{

Application.Exit();

}

eof = buffer;

}

bits_to_go = 8;

}

// Выдача очередного бита с правого конца

t = buffer & 1;

buffer >>= 1;

bits_to_go -= 1;

return t;

}

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

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

public void start_outputing_bits ()

{

buffer = 0;

bits_to_go = 8;

}

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

// Вывод очередного бита сжатой информации

public void output_bit(int bit)

{

// Бит - в начало буфеpа

buffer >>= 1;

if (bit == 1)

buffer |= 0x80;

bits_to_go -= 1;

// Вывод полного буфера

if (bits_to_go == 0)

{

dataout.WriteByte((byte)buffer);

bits_to_go = 8;

}

}

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

// Очистка буфера побитового вывода

public void done_outputing_bits ()

{

dataout.WriteByte((byte)(buffer >> bits_to_go));

}

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

// Вывод указанного бита и отложенных ранее

public void output_bit_plus_follow(int bit)

{

output_bit(bit);

while (bits_to_follow > 0)

{

output_bit(~bit + 2);

bits_to_follow--;

}

}

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

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

public void start_encoding()

{

// Полный кодовый интервал

low = 0L;

high = top_value;

bits_to_follow = 0L;

}

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

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

public void done_encoding ()

{

/* Вывод двух бит, определяющих четверть, лежащую в текущем интервале */

bits_to_follow++;

if (low < first_qtr)

output_bit_plus_follow (0);

else

output_bit_plus_follow (1);

}

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

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

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

void start_decoding ()

{

int i;

int a;

value = 0L;

// Воод бит для заполнения значения кода

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

{

a = input_bit();

value = 2 * value + a;

}

// Текущий интервал равен исходному

low = 0L;

high = top_value;

}

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

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

public void encode_symbol(int symbol)

{

// Ширина текущего кодового интервала

long range;

range = (long)(high - low) + 1;

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

high = low + (range*cum_freq[symbol - 1]) / cum_freq[0] - 1;

low = low + (range*cum_freq[symbol]) / cum_freq[0];

// Вывод битов

for ( ; ; )

{

// Если в нижней половине

if (high < half)

output_bit_plus_follow(0);

// Если в верхней половине

else if (low >= half)

{

output_bit_plus_follow(1);

low -= half;

high -= half;

}

/* Если текущий интервал содержит середину, то вывод еще одного обратного бита позже */

else if (low >= first_qtr && high < third_qtr)

{

bits_to_follow += 1;

low -= first_qtr;

high -= first_qtr;

}

else

break;

// Расширить текущий рабочий кодовый интервал

low = 2 * low;

high = 2 * high + 1;

}

}

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

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

int decode_symbol ()

{

// Ширина интервала

long range;

// Накопленная частота

int cum;

// Декодируемый символ

int symbol;

int a;

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

range = (long) (high - low) + 1;

// Hахождение значения накопленной частоты для value

cum=(int)((((long)(value-low)+1)*cum_freq[0]-1)/ range);

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

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

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

high = low + (range*cum_freq[symbol - 1]) / cum_freq[0] - 1;

low = low + (range * cum_freq [symbol]) / cum_freq [0];

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

for (;;)

{

// Расширение нижней половины

if (high < half)

{

}

// Расширение верхней половины

else if (low >= half)

{

value -= half;

low -= half;

high -= half;

}

// Расширение середины

else if (low >= first_qtr && high < third_qtr)

{

value -= first_qtr;

low -= first_qtr;

high -= first_qtr;

}

else

break;

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

low = 2 * low;

high = 2 * high + 1;

// Добавить новый бит

a = input_bit();

value = 2 * value + a;

}

return symbol;

}

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

// Собственно адаптивное арифметическое кодирование

public void encode(string infile, string outfile)

{

int ch, symbol;

try

{

dataout = new FileStream(outfile, FileMode.Create);

}

catch (IOException exc)

{

return;

}

try

{

datain = new FileStream(infile, FileMode.Open);

}

catch (FileNotFoundException exc)

{

return;

}

start_model();

start_outputing_bits();

start_encoding();

// Цикл обработки символов

for ( ; ; )

{

try

{

// Чтение исходного символа

ch = datain.ReadByte();

}

catch (Exception exc)

{

return;

}

// Выход при достижении конца файла

if (ch == -1)

break;

// Найти рабочий символ

symbol = char_to_index[ch];

// Закодировать символ

encode_symbol(symbol);

// Обновить модель

update_model(symbol);

}

// Закодировать символ конца файла

encode_symbol(eof_symbol);

// Завершение кодирования

done_encoding();

done_outputing_bits();

dataout.Close();

datain.Close();

}

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

// Собственно адаптивное арифметическое декодирование

void decode(string infile, string outfile)

{

int ch, symbol;

try

{

dataout = new FileStream(outfile, FileMode.Create);

}

catch (IOException exc)

{

return;

}

try

{

datain = new FileStream(infile, FileMode.Open);

}

catch (FileNotFoundException exc)

{

return;

}

start_model ();

start_inputing_bits ();

start_decoding ();

// Цикл обработки сиволов

for (;;)

{

// Получаем индекс символа

symbol = decode_symbol ();

if (symbol == eof_symbol)

break;

// Получаем декодированный символ

ch = index_to_char [symbol];

// Записываем в выходной файл

dataout.WriteByte((byte)ch);

// Обновляем модель

update_model (symbol);

}

dataout.Close();

datain.Close();

}

Приложение 2. Интерфейс программы

Примечание. Для работы программы необходим Microsoft .NET Framework 2.0.

Страницы: 1, 2, 3, 4, 5, 6



2012 © Все права защищены
При использовании материалов активная ссылка на источник обязательна.