Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Архив2 / курсач docx283 / naydenov_kursach_lzv.docx
Скачиваний:
67
Добавлен:
07.08.2013
Размер:
82.19 Кб
Скачать

Список литературы

  1. Stutz, Michael Get started with GAWK: AWK language fundamentals.developerWorks. IBM(September 19, 2006). — «[AWK] часто называют языком, управляемым данными -- операторы программы описывают подходящие входные данные и их обработку, а не последовательность шагов программы»Архивированоиз первоисточника 2 сентября 2012. Проверено 23 октября 2010.

  2. (1989) «Object-oriented design: a responsibility-driven approach». Conference Proceedings on Object-Oriented Programming Systems, Languages and Applications (ACM): 71–75.DOI:10.1145/74877.74885.

  3. http://ru.wikipedia.org/wiki/Сжатие_данных

  4. http://ru.wikipedia.org/wiki/Алгоритм_Лемпеля_-_Зива_-_Велча

  5. http://ru.wikipedia.org/wiki/Событийно_ориентированное_программирование

  6. http://ru.wikipedia.org/wiki/Программирование_потоком_данных

Блок-схема Листинг программы

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

/************************************************************************

** Демонстрационная программа для LZW-алгоритма сжатия/распаковки данных.

** Mark R. Nelson

*************************************************************************/

#include <stdio.h>

#define BITS 12 /* Установка длины кода равной 12, 13 */

#define HASHING_SHIFT BITS-8 /* или 14 битам. */

#define MAX_VALUE (1 << BITS) - 1/* Отметим, что на MS-DOS-машине при */

#define MAX_CODE MAX_VALUE - 1 /* длине кода 14 бит необходимо компи- */

/* лировать, используя large-модель. */

#if BITS == 14

#define TABLE_SIZE 18041 /* Размер таблицы строк должен быть */

#endif /* простым числом, несколько большим, */

#if BITS == 13 /* чем 2**BITS. */

#define TABLE_SIZE 9029

#endif

#if BITS <= 12

#define TABLE_SIZE 5021

#endif

enum STATES {

NAME, SIZE, DATA

};

typedef struct {

char ** frames;

Int n_files;

int i; // current file index

FILE *f; // current file

char buf[1024];

int buf_pos;

int buf_len;

} InArchStream;

typedef struct {

int state; // статус (1,2,3) (1- читаю имя файла, 2 читаю инфу о длине(4 байта), 3 читаю само тело файла)

char fname [1050]; //

int fname_pos; // позиция на имени

int flen; // длина файла походу(4 байта которые.)

FILE * out; // сам файл

int flen_count; // счетчик по длине файла(от 0 байта до 4 байта)

int out_count; //

} OutArchStream;

struct context

{

/* Это массив для значений кодов */

int *code_value; //izbavlyaemsya ot globalnih peremennyh.

/* Этот массив содержит префиксы кодов */

unsigned int *prefix_code;

/* Этот массив содержит добавочные символы */

unsigned char *append_character;

/* Этот массив содержит декодируемые строки */

unsigned char decode_stack[4000];

};

/*

** Следующие две процедуры управляют вводом/выводом кодов

** переменной длины. Они для ясности написаны чрезвычайно

** простыми и не очень эффективны.

*/

int input_code(FILE *input)

{

unsigned int return_value;

static int input_bit_count=0;

static unsigned long input_bit_buffer=0L;

while (input_bit_count <= 24)

{

input_bit_buffer|=(unsigned long)getc(input)<<(24-input_bit_count);

input_bit_count += 8;

}

return_value=input_bit_buffer >> (32-BITS);

input_bit_buffer <<= BITS;

input_bit_count -= BITS;

return(return_value);

}

int output_code(FILE *output,unsigned int code)

{

static int output_bit_count=0;

static unsigned long output_bit_buffer=0L;

output_bit_buffer|=(unsigned long)code<<(32-BITS-output_bit_count);

output_bit_count += BITS;

while (output_bit_count >= 8)

{

putc(output_bit_buffer >> 24,output);

output_bit_buffer <<= 8;

output_bit_count -= 8;

}

}

int arch_get_c(InArchStream * stream){

while (1) {

int a;

if (stream->buf_pos<stream->buf_len){

a=(unsigned char)stream->buf[stream->buf_pos];

stream->buf_pos++;

return a;

}

if (stream->f==NULL){

if (stream->i==stream->n_files)

return -1;

stream->f=fopen(stream->frames[stream->i], "rb");

if(stream->f==NULL)

return -1;

strcpy(stream->buf,stream->frames[stream->i]);

fseek(stream->f, 0, SEEK_END);

int size = ftell(stream->f);

fseek(stream->f, 0, SEEK_SET);

int fname_len=strlen(stream->buf);

*(int *)&stream->buf[fname_len+1] = size;

stream->buf_len=fname_len+5;

stream->buf_pos=0;

continue;

}

int n =fread(stream->buf,1,sizeof(stream->buf),stream->f);

stream->buf_pos=0;

stream->buf_len=n;

if (stream->buf_len == 0) {

fclose(stream->f);

stream->f=NULL;

stream->i++;

}

}

}

int arch_put_c(char c, OutArchStream * stream) {

char * bytes;

switch (stream->state) {

case NAME:

stream->fname[stream->fname_pos++] = c;

if (c == 0) {

stream->state = SIZE;

stream->out_count = 0;

}

break;

case SIZE:

bytes = (char *)(&stream->flen);

bytes[stream->out_count++] = c;

if (stream->out_count == 4) {

stream->state = DATA;

stream->out = NULL;

}

break;

case DATA:

if (stream->out == NULL) {

stream->out = fopen(stream->fname, "wb");

stream->flen_count = 0;

}

putc(c, stream->out);

stream->flen_count ++;

if (stream->flen_count == stream->flen) {

fclose(stream->out);

stream->state = NAME;

}

break;

}

}

/*

** Процедура хэширования. Она пытается найти сопоставление для строки

** префикс+символ в таблице строк. Если найдено, возвращается индекс.

** Если нет, то возвращается первый доступный индекс.

*/

int find_match(int hash_prefix,unsigned int hash_character,struct context *ctx){

int index;

int offset;

index = (hash_character << HASHING_SHIFT) ^ hash_prefix;

if (index == 0)

offset = 1;

else

offset = TABLE_SIZE - index;

while (1)

{

if (ctx->code_value[index] == -1)

return(index);

if (ctx->prefix_code[index]==hash_prefix&&ctx->append_character[index]==hash_character)

return(index);

index -= offset;

if (index < 0)

index += TABLE_SIZE;

}

}// end of find_math;

/*

** Процедура сжатия.

*/

int compress(InArchStream *input, FILE *output, struct context *ctx){

unsigned int next_code;

unsigned int character;

unsigned int string_code;

unsigned int index;

int i;

next_code=256; /* Next_code - следующий доступный код строки */

for (i=0;i<TABLE_SIZE;i++)/*Очистка таблицы строк перед стартом */

ctx->code_value[i]=-1;

i=0;

printf("Compressing...\n");

string_code=arch_get_c(input); /* Get the first code*/

/*

** Основной цикл. Он выполняется до тех пор, пока возможно чтение

** входного потока. Отметим, что он прекращает заполнение таблицы

** строк после того, как все возможные коды были использованы.

*/

while ((character=arch_get_c(input)) != (unsigned)EOF)

{

if (++i==1000) /* Печатает * через каждые 1000 */

{ /* чтений входных символов (для */

i=0; /* умиротворения зрителя). */

printf("*");

}

/* Смотрит, есть ли строка */

index=find_match(string_code,character,ctx);

if (ctx->code_value[index] != -1) /* в таблице. Если есть,*/

string_code=ctx->code_value[index];/* получает значение кода*/

else /* Если нет, добавляет ее*/

{ /* в таблицу. */

if (next_code <= MAX_CODE)

{

ctx->code_value[index]=next_code++;

ctx->prefix_code[index]=string_code;

ctx->append_character[index]=character;

}

output_code(output,string_code);/*Когда обнаруживается, что*/

string_code=character; /*строки нет в таблице, */

} /*выводится последняя строка*/

} /*перед добавлением новой */

/*

** End of the main loop.

*/

output_code(output,string_code); /* Вывод последнего кода */

output_code(output,MAX_VALUE); /* Вывод признака конца потока */

output_code(output,0); /* Очистка буфера вывода */

printf("\n");

} //end of compress();

/*

** Процедура распаковки. Она читает файл LZW-формата и распаковывает

** его в выходной файл.

*/

Соседние файлы в папке курсач docx283