{
a = input_bit();
value = 2 * value + a;
}
// Текущий интервал равен исходному
low = 0L;
high = top_value;
}
//------------------------------------------------------------
// Кодирование очередного символа
public void encode_symbol(int symbol)
{
// Ширина текущего кодового интервала
longrange;
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 .NETFramework 2.0.