{
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;
// Вывод очередного бита сжатой информации
public void output_bit(int bit)
// Бит - в начало буфеpа
if (bit == 1)
buffer |= 0x80;
// Вывод полного буфера
if (bits_to_go == 0)
dataout.WriteByte((byte)buffer);
// Очистка буфера побитового вывода
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;
// Текущий интервал равен исходному
// Кодирование очередного символа
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;
break;
// Расширить текущий рабочий кодовый интервал
low = 2 * low;
high = 2 * high + 1;
// Декодирование очередного символа
int decode_symbol ()
// Ширина интервала
// Накопленная частота
int cum;
// Декодируемый символ
int symbol;
// Определение текущего масштаба частот
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++);
// Пересчет границ
low = low + (range * cum_freq [symbol]) / cum_freq [0];
// Удаление очередного символа из входного потока
for (;;)
// Расширение нижней половины
// Расширение верхней половины
value -= half;
// Расширение середины
value -= first_qtr;
// Увеличение масштаба интервала
// Добавить новый бит
return symbol;
//--------------------------------------------------------------
// Собственно адаптивное арифметическое кодирование
public void encode(string infile, string outfile)
int ch, symbol;
try
dataout = new FileStream(outfile, FileMode.Create);
catch (IOException exc)
return;
datain = new FileStream(infile, FileMode.Open);
catch (FileNotFoundException exc)
start_model();
start_outputing_bits();
start_encoding();
// Цикл обработки символов
// Чтение исходного символа
ch = datain.ReadByte();
catch (Exception exc)
// Выход при достижении конца файла
if (ch == -1)
// Найти рабочий символ
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)
start_model ();
start_inputing_bits ();
start_decoding ();
// Цикл обработки сиволов
// Получаем индекс символа
symbol = decode_symbol ();
if (symbol == eof_symbol)
// Получаем декодированный символ
ch = index_to_char [symbol];
// Записываем в выходной файл
dataout.WriteByte((byte)ch);
// Обновляем модель
update_model (symbol);
Приложение 2. Интерфейс программы
Примечание. Для работы программы необходим Microsoft .NET Framework 2.0.
Страницы: 1, 2, 3, 4, 5, 6