Автор работы: Пользователь скрыл имя, 12 Января 2014 в 01:29, курсовая работа
Написати програму, яка реалізує алгоритм арифметичного кодування-декодування, що виконує стиснення інформації. На вході програма повинна отримати файл, а на виході цей файл повинен бути закодованим. Також реалізувати декодування цього файлу. Порівняти ефективність стиснення з різними форматами файлів. Програма має виконувати такі функції:
надавати користувачу можливість кодувати та декодувати файли;
забезпечити максимальну надійність при кодуванні та декодуванні;
надавати можливість порівняння кодованого та декодованого файлу;
3.1. Вибір мови та середовища програмування
В якості мови програмування я вибрав C#, оскільки ця мова є об’єктно- орієнтованою, має безпечну систему типізації і надає широкий вибір інструментів для розробника. Дане програмне забезпечення написано під платформу Microsoft .Net Framework 3.5 і вище.
Утиліта буде написана в середовищі програмуванні Microsoft Visual Studio 2010, оскільки дане середовище має зручний інтерфейс, широкий набір інструментів для створення графічного інтерфейсу користувача, інтерфейс для багатопотоковї розробки. Також дуже важливою особливістю даного середовища є легкість тестування та від лагодження програмних продуктів, які в ньому розробляються.
3.2. Бібліотеки, які
використовуються при
3.3. Розробка блок-схеми роботи програми кодування
Блок-схема роботи програми кодування наведена на Рис. 3.1
Рис. 3.1 Блок-схема роботи програми кодування
Ні
Так
Рис. 3.1 «продовження»
Опис блок-схеми роботи програми кодування
Потрібний файл вибирається за допомогою системного виклику DialogResult result = openFileDialog1.ShowDialog().
Якщо файл був успішно відкритий if (result == DialogResult.OK), то наступним кроком буде створення хендлу вхідного файлу, для подальшого визначення його розміру системною функцією GetFileSizeEx(handle, out fileSize).
Послідовність дій при
створенні вихідного файлу така
сама, як і в пункті (2), тільки з
однією відмінністю: замість функції openFileDialog
Програма повинна працювати з моделлю, яка надає пару перекодованих таблиць index_to_char [] і char_to_index [], і масив накопичених частот cum_freq []. Причому до нього висуваються такі вимоги:
cum_freq [i-1]> = cum_freq [i];
ніколи не робиться спроба кодувати символ [i], для якого:
cum_freq [i-1] = cum_freq [i];
cum_freq [0] <= Max_frequency.
Якщо дані умови дотримані, значення в масиві не повинні мати зв'язку з дійсними значеннями накопичених частот символів тексту.
public void start_model()
{
int i;
// Встановлення таблиць перекодування
for (i = 0; i < no_of_chars; i++)
{
char_to_index[i] = i + 1;
index_to_char[i + 1] = i;
}
// Встановлення лічильника частот
for (i = 0; i <= no_of_symbols; i++)
{
freq[i] = 1;
cum_freq[i] = no_of_symbols - i;
}
freq[0] = 0;
}
В даному кроці встановлюються початкові значення для подальшого кодування.
public void start_outputing_bits()
{
buffer = 0;
bits_to_go = 8;
}
public void start_encoding()
{
// Повний кодовий інтервал
low = 0L;
high = top_value;
bits_to_follow = 0L;
}
Спершу, завантажується перший символ файлу і передається на кодування.
Кодування одного символу
виконує функція encode_symbol(
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;
}
}
Після цих кроків робиться перевірка на кінець файлу
if (ch == -1)
break;
Якщо файл ще не закінчився, то попередні дії виконуються ще раз
dataout.Close();
datain.Close();
а також визначається розмір вихідного файлу за допомогою функції GetFileSizeEx(), якій у параметри передаєть хендл вихідного файлу та змінна, у яку буде збережно розмір файлу.
3.4. Розробка блок-схеми роботи програми декодування
Блок-схема роботи програми декодування наведена на Рис. 3.2
Ні
Так
Рис. 3.2 Блок-схема роботи програми декодування
Рис. 3.2 «продовження»
Опис блок-схеми роботи програми декодування
Потрібний файл вибирається за допомогою системного виклику DialogResult result = openFileDialog1.ShowDialog();
Якщо файл був успішно відкритий if (result == DialogResult.OK), то наступним кроком буде створення хендлу вхідного файлу, для подальшого визначення його розміру системною функцією GetFileSizeEx(handle, out fileSize).
Послідовність дій при
створенні вихідного файлу така
сама, як і в пункті (2), тільки з
однією відмінністю: замість функції openFileDialog
Програма повинна працювати з моделлю, яка надає пару перекодованих таблиць index_to_char [] і char_to_index [], і масив накопичених частот cum_freq []. Причому до нього висуваються такі вимоги:
cum_freq [i-1]> = cum_freq [i];
ніколи не робиться спроба кодувати символ [i], для якого:
cum_freq [i-1] = cum_freq [i];
cum_freq [0] <= Max_frequency.
Якщо дані умови дотримані, значення в масиві не повинні мати зв'язку з дійсними значеннями накопичених частот символів тексту.
public void start_model()
{
int i;
// Встановлення таблиць перекодування
for (i = 0; i < no_of_chars; i++)
{
char_to_index[i] = i + 1;
index_to_char[i + 1] = i;
}
// Встановлення лічильника частот
for (i = 0; i <= no_of_symbols; i++)
{
freq[i] = 1;
cum_freq[i] = no_of_symbols - i;
}
freq[0] = 0;
}
void start_inputing_bits()
{
bits_to_go = 0;
garbage_bits = 0;
}
buffer = datain.ReadByte(), який згодом передається на вхід функції decode_symbol(), яка виконує декодування і запис вже декодованого символу у вихідний файл.
int decode_symbol()
{
// Ширина інтервалу
long range;
// Накопичена частота
int cum;
// символ, який декодується
int symbol;
int a;
// Визначення поточної частоти
range = (long)(high - low) + 1;
// Знаходження значення накопиченої частоти
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;
}
Після цих кроків виконується перевірка на кінець файлу. Якщо файл ще не закінчився, то цей крок повторюється знову, якщо файл закінчився, то переходимо до наступного етапу.
Информация о работе Утиліта стискання файлів за алгоритмом арифметичного кодування