PDA

Показать полную графическую версию : упаковщик LZW


mephistophel
26-04-2010, 18:00
помогите пожалуйста исправить ошибки в коде:
#include <ctype.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*-константы используемые при работе лзв
*/
/* количество битов в коде */
#define BITS 12
/* максимальное значение кода* */
#define MAX_CODE ( ( 1 << BITS ) - 1 )
/* размер словаря элементов */
#define TABLE_SIZE 5021
/* код конца потока* */
#define END_OF_STREAM 256
/* значение кода получаемое первой добавленной в словарь фразой* */
#define FIRST_CODE 257
/* признак свободной ячейки в словаре */
#define UNUSED -1


typedef unsigned char uchar;
typedef unsigned long ulong;
typedef unsigned int uint;

/*---------------------------------------------------------
Побитовый доступ к файлам
*/

typedef struct bfile
{
BFILE *bfile;
uchar mask;
int rack;
int pacifier_counter;
};
BFILE;


#define PACIFIER_COUNT 2047


/*---------------------------------------------------------
функции высокого уровня
*/
void print_ratios ( char *input, char *output );
void Arhiv ( BFILE *input, BFILE *output );
void DeArhiv ( BFILE *input, FILE *output );
long file_size ( char *name );
void messege_complite ( char *prog_name );
/*---------------------------------------------------------
прочие функции необходимые для работы программы
*/
BFILE *OpenInputBFile ( char *name );
BFILE *OpenOutputBFile ( char *name );
void WriteBit ( BFILE *bfile, int bit );
ulong WriteBits ( BFILE *bfile, ulong code, int count );
int ReadBit ( BFILE *bfile );
ulong ReadBits ( BFILE *bfile, int bit_count );
void CloseInputBFile ( BFILE *bfile );
void CloseOutputBFile ( BFILE *bfile );

/*---------------------------------------------------------
функции работы с моделью данных для алгоритма лзв
*/

uint find_dictionary_match ( int prefix_code, int character );
uint decode_string ( uint offset, uint code );



char *CompressionName = "LZW 12-bit Coder";
char *Usage = "input file-output file\n\n";

void fatal_error( char *str, ... );

/*-----------------------------------------------------------
головная процедура*.
*/

void main(void)
{
char ch;
char filename_in[256];
char filename_out[256];
int i;

BFILE *output;
FILE *input, *output2;

clrscr();
setbuf( stdout, NULL );
printf("\nPlease chose the procedure:");
printf("\n1.Compress file");
printf("\n2.Decompres file");
printf("\n3. Stop and Exit!=)");
printf("\nEnter your choyse: ");
ch=getche();
switch (ch)
{
case '1':
{
for(i=0;i<256;i++)
{
filename_in[i]=filename_out[i]=NULL;
}
printf("\nEnter name of input file: ");
gets(filename_in);
input = fopen( filename_in, "rb" );
if ( input == NULL )
fatal_error( "Error to open %s for input\n", filename_in);

printf("\nEnter name of output file: ");
gets(filename_out);
output = OpenOutputBFile( filename_out);
if ( output == NULL )
fatal_error( "Error to open %s for output\n", filename_out);

printf( "\nPlease wait-Compresing... %s in %s\n", filename_in, filename_out );
printf( "Using %s\n", CompressionName );
Arhiv( input, output );
CloseOutputBFile( output );
fclose( input );
print_ratios( filename_in, filename_out );
}
break;
case '2':
{
for(i=0;i<256;i++)
{
filename_in[i]=filename_out[i]=NULL;
}
printf("\nEnter name of input file: ");
gets(filename_in);
output = OpenInputBFile( filename_in);
if ( output == NULL )
fatal_error( "Error to open %s for input\n", filename_in);

printf("\nEnter name of output file: ");
gets(filename_out);
output2 = fopen( filename_out, "wb");
if ( output2 == NULL )
fatal_error( "Error to open %s for output\n", filename_out);

printf( "\nPlease wait-Decompresing... %s in %s\n", filename_in, filename_out );
printf( "Using %s\n", CompressionName );
ExpandFile( output, output2 );
CloseOutputBFile( output );
fclose( output2 );
print_ratios( filename_in, filename_out );
}
break;
case '3':
{
}break;
}

getch();

}

/*-----------------------------------------------------------
обработка фатальной ошибки при работе программы.
*/

void fatal_error( char *str, ... )
{
printf( "Fatal Error: %s\n", str );
exit(1);
}

/*-----------------------------------------------------------
открытие файла для побитовой записи
*/

BFILE *OpenOutputBFile ( char * name )
{
BFILE *bfile;

bfile = (BFILE *) calloc( 1, sizeof( BFILE ) );
bfile->file = fopen( name, "wb" );
bfile->rack = 0;
bfile->mask = 0x80;
bfile->pacifier_counter = 0;
return bfile;
}

/*-----------------------------------------------------------
открытие файла для побитового чтения
*/

BFILE *OpenInputBFile( char *name )
{
BFILE *bfile;

bfile = (BFILE *) calloc( 1, sizeof( BFILE ) );
bfile->file = fopen( name, "rb" );
bfile->rack = 0;
bfile->mask = 0x80;
bfile->pacifier_counter = 0;
return bfile;
}

/*-----------------------------------------------------------
закрытие файла для побитовой записи
*/

void CloseOutputBFile ( BFILE *bfile )
{
if ( bfile->mask != 0x80 )
putc( bfile->rack, bfile->file );
fclose ( bfile->file );
free ( (char *) bfile );
}

/*-----------------------------------------------------------
закрытие файла для опбитового чтения
*/

void CloseInputBFile ( BFILE *bfile )
{
fclose ( bfile->file );
free ( (char *) bfile );
}

/*-----------------------------------------------------------
вывод одного бита*
*/

void WriteBit ( BFILE *bfile, int bit )
{
if ( bit )
bfile->rack |= bfile->mask;
bfile->mask >>= 1;
if ( bfile->mask == 0 )
{
putc( bfile->rack, bfile->file );
if ( ( bfile->pacifier_counter++ & PACIFIER_COUNT ) == 0 )
putc( '.', stdout );
bfile->rack = 0;
bfile->mask = 0x80;
}
}

/*-----------------------------------------------------------
вывод нескольких битов
*/

void WriteBits( BFILE *bfile, ulong code, int count )
{
ulong mask;

mask = 1L << ( count - 1 );
while ( mask != 0)
{
if ( mask & code )
bfile->rack |= bfile->mask;
bfile->mask >>= 1;
if ( bfile->mask == 0 )
{
putc( bfile->rack, bfile->file );
if ( ( bfile->pacifier_counter++ & PACIFIER_COUNT ) == 0 )
putc( '.', stdout );
bfile->rack = 0;
bfile->mask = 0x80;
}
mask >>= 1;
}
}

/*-----------------------------------------------------------
‚Ввод дного бита
*/

int ReadBit( BFILE *bfile )
{
int value;

if ( bfile->mask == 0x80 )
{
bfile->rack = getc( bfile->file );
if ( bfile->rack == EOF )
fatal_error( "Error in procedure ReadBit! Something wrong, chek it!\n" );
if ( ( bfile->pacifier_counter++ & PACIFIER_COUNT ) == 0 )
putc( '.', stdout );
}

value = bfile->rack & bfile->mask;
bfile->mask >>= 1;
if ( bfile->mask == 0 )
bfile->mask = 0x80;
return ( value ? 1 : 0 );
}

/*-----------------------------------------------------------
ввод нескольких битов
*/

ulong ReadBits ( BFILE *bfile, int bit_count )
{
ulong mask;
ulong return_value;

mask = 1L << ( bit_count - 1 );
return_value = 0;
while ( mask != 0 )
{
if ( bfile->mask == 0x80 )
{
bfile->rack = getc( bfile->file );
if ( bfile->rack == EOF )
fatal_error( "Error in procedure ReadBits (not ReadBit)! Something wrong, chek it!\n" );
if ( ( bfile->pacifier_counter++ & PACIFIER_COUNT ) == 0 )
putc( '.', stdout );
}
if ( bfile->rack & bfile->mask )
return_value |= mask;
mask >>= 1;
bfile->mask >>= 1;
if ( bfile->mask == 0 )
bfile->mask = 0x80;
}

return return_value;
}


/*-----------------------------------------------------------
вывод сообщения об использовании
*/

void messege_complite ( char *prog_name )
{
char *short_name;
char *extension;

short_name = strrchr( prog_name, '\\' );
if ( short_name == NULL )
short_name = strrchr( prog_name, '/' );
if ( short_name == NULL )
short_name = strrchr( prog_name, ':' );
if ( short_name != NULL )
short_name++;
else
short_name = prog_name;
extension = strrchr( short_name, '.' );
if ( extension != NULL )
*extension = '\0';
printf( "\nUsing: %s %s\n", short_name, Usage );
exit( 0 );
}

/*-----------------------------------------------------------
измерение длинны файла
*/

long file_size ( char *name )
{
long eof_ftell;
FILE *file;

file = fopen( name, "r" );
if ( file == NULL )
return( 0L );
fseek( file, 0L, SEEK_END );
eof_ftell = ftell( file );
fclose( file );
return eof_ftell;
}

/*-----------------------------------------------------------
вывод сообщения о соотношении размеров файлов
*/
void print_ratios( char *input, char *output )
{
long input_size;
long output_size;
int ratio;

input_size = file_size( input );
if ( input_size == 0 )
input_size = 1;
output_size = file_size( output );
ratio = 100 - (int) ( output_size * 100L / input_size );
printf( "\nByte in: %ld\n", input_size );
printf( "Byte out: %ld\n", output_size );
if ( output_size == 0 )
output_size = 1;
printf( "Compression degree: %d%%\n", ratio );
}

/*-----------------------------------------------------------
„Алгоритм ЛЗВ:
*/

/* ‘структура словаря */

struct dictionary
{
int code_value;
int prefix_code;
char character;
}
dict[TABLE_SIZE];

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

char decode_stack[TABLE_SIZE];

/*-----------------------------------------------------------
сжатие файла:
*/

void Arhiv ( FILE *input, BFILE *output )
{
int next_code, character, string_code;
uint index, i;

/* инициализация */
next_code = FIRST_CODE;
for ( i = 0 ; i < TABLE_SIZE ; i++ )
dict[i].code_value = UNUSED;
/* ‘считать первый символ */
if ( ( string_code = getc( input ) ) == EOF )
string_code = END_OF_STREAM;
/* пока не конец сообщения */
while ( ( character = getc( input ) ) != EOF )
{
/* попытка найти в словаре фразу <фраза*, символ> */
index = find_dictionary_match ( string_code, character );
/* соответствие найдено*/
if ( dict[index].code_value != -1 )
string_code = dict[index].code_value;
/* ’такой пары в словаре нет */
else
{
/* „добавление в словарь */
if ( next_code <= MAX_CODE )
{
dict[index].code_value = next_code++;
dict[index].prefix_code = string_code;
dict[index].character = (char) character;
}
/* выдача кода */
WriteBits( output, (ulong) string_code, BITS );
string_code = character;
}
}
/* завершение кодирования */
WriteBits( output, (ulong) string_code, BITS );
WriteBits( output, (ulong) END_OF_STREAM, BITS );
}

/*-----------------------------------------------------------
извлечение сжатого фала (декодирование)
*/

void DeArhiv( BFILE *input, FILE *output )
{
uint next_code, new_code, old_code;
int character;
uint count;

next_code = FIRST_CODE;
old_code = (uint) ReadBits( input, BITS );
if ( old_code == END_OF_STREAM )
return;
character = old_code;

putc ( old_code, output );

while ( ( new_code = (uint) ReadBits( input, BITS ) )
!= END_OF_STREAM )
{
/* обработка неожиданной ситуации */
if ( new_code >= next_code )
{
decode_stack[ 0 ] = (char) character;
count = decode_string( 1, old_code );
}
else
count = decode_string( 0, new_code );

character = decode_stack[ count - 1 ];
/* выдача раскодированной строки */
while ( count > 0 )
putc( decode_stack[--count], output );
/* обновление словаря */
if ( next_code <= MAX_CODE )
{
dict[next_code].prefix_code = old_code;
dict[next_code].character = (char) character;
next_code++;
}
old_code = new_code;
}
}

/*-----------------------------------------------------------
процедура поиска в словаре указанной пары (код фразы, символ).
используеться хеш, получаемый из параметров
*/

uint find_dictionary_match ( int prefix_code, int character )
{
int index;
int offset;

/* получение значения хеш функции */
index = ( character << ( BITS - 8 ) ) ^ prefix_code;
/* разрешение возможных коллизий
Коллизией хеш-функции H называется два различных входных блока данных x и y таких, что H(x) = H(y).

Коллизии существуют для большинства хеш-функций, но для «хороших» хеш-функций частота их возникновения близка к теоретическому минимуму.
В некоторых частных случаях, когда множество различных входных данных конечно, можно задать инъективную хеш-функцию, по определению не
имеющую коллизий. Однако, для функций, принимающих вход переменной длины и возвращающих хеш постоянной длины (такие, как MD5), коллизии
обязаны существовать, поскольку хотя бы для одного значения хеш-функции соответствующее ему множество входных данных будет бесконечно —
и любые два набора данных из этого множества образуют коллизию. */
if ( index == 0 )

offset = 1;
else
offset = TABLE_SIZE - index;
for ( ; ; )
{
/* ячейка словаря не использована*** */
if ( dict[index].code_value == UNUSED )
return index;
/* найдено соответствие */
if ( dict[index].prefix_code == prefix_code &&
dict[index].character == (char) character )
return index;
/* коллизия.. попытка ее разрешения */
index -= offset;
if ( index < 0 )
index += TABLE_SIZE;
}
}

/*-----------------------------------------------------------
декодирование тсроки. процедура размещает символы в стеке, возвращая их количество
*/

uint decode_string ( uint count, uint code )
{
while ( code > 255 ) /*пока не встретитсья код символа* */
{
decode_stack[count++] = dict[code].character;
code = dict[code].prefix_code;
}
decode_stack[count++] = (char) code;
return count;
}

1>------ Build started: Project: фыва, Configuration: Debug Win32 ------
1>Compiling...
1>фыва.cpp
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(32) : error C2143: syntax error : missing ';' before '*'
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(32) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(32) : error C2461: 'bfile' : constructor syntax missing formal parameters
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(36) : warning C4091: 'typedef ' : ignored on left of 'bfile' when no variable is declared
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(37) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(47) : error C2065: 'input' : undeclared identifier
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(47) : error C2065: 'output' : undeclared identifier
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(47) : error C2182: 'Arhiv' : illegal use of type 'void'
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(47) : error C2078: too many initializers
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(48) : error C2065: 'input' : undeclared identifier
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(48) : error C2065: 'FILE' : undeclared identifier
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(48) : error C2065: 'output' : undeclared identifier
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(48) : error C2182: 'DeArhiv' : illegal use of type 'void'
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(48) : error C2078: too many initializers
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(54) : error C2143: syntax error : missing ';' before '*'
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(54) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(54) : error C2086: 'int BFILE' : redefinition
1> d:\программы\новая папка\фыва\фыва\фыва.cpp(37) : see declaration of 'BFILE'
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(54) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(55) : error C2143: syntax error : missing ';' before '*'
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(55) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(55) : error C2086: 'int BFILE' : redefinition
1> d:\программы\новая папка\фыва\фыва\фыва.cpp(37) : see declaration of 'BFILE'
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(55) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(56) : error C2275: 'bfile' : illegal use of this type as an expression
1> d:\программы\новая папка\фыва\фыва\фыва.cpp(31) : see declaration of 'bfile'
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(56) : error C2062: type 'int' unexpected
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(57) : error C2275: 'bfile' : illegal use of this type as an expression
1> d:\программы\новая папка\фыва\фыва\фыва.cpp(31) : see declaration of 'bfile'
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(57) : error C2275: 'ulong' : illegal use of this type as an expression
1> d:\программы\новая папка\фыва\фыва\фыва.cpp(23) : see declaration of 'ulong'
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(57) : error C2146: syntax error : missing ')' before identifier 'code'
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(57) : error C2078: too many initializers
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(57) : error C2275: 'ulong' : illegal use of this type as an expression
1> d:\программы\новая папка\фыва\фыва\фыва.cpp(23) : see declaration of 'ulong'
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(57) : error C2059: syntax error : ')'
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(58) : error C2275: 'bfile' : illegal use of this type as an expression
1> d:\программы\новая папка\фыва\фыва\фыва.cpp(31) : see declaration of 'bfile'
1>d:\программы\новая папка\фыва\фыва\фыва.cpp(58) : fatal error C1903: unable to recover from previous error(s); stopping compilation
1>Build log was saved at "file://d:\Программы\Новая папка\фыва\фыва\Debug\BuildLog.htm"
1>фыва - 31 error(s), 1 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Awejk
26-04-2010, 19:47
#define _CRT_SECURE_NO_WARNINGS
#include <ctype.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*-константы используемые при работе лзв
*/
/* количество битов в коде */
#define BITS 12
/* максимальное значение кода* */
#define MAX_CODE ( ( 1 << BITS ) - 1 )
/* размер словаря элементов */
#define TABLE_SIZE 5021
/* код конца потока* */
#define END_OF_STREAM 256
/* значение кода получаемое первой добавленной в словарь фразой* */
#define FIRST_CODE 257
/* признак свободной ячейки в словаре */
#define UNUSED -1


typedef unsigned char uchar;
typedef unsigned long ulong;
typedef unsigned int uint;
void clrscr(void);

/*---------------------------------------------------------
Побитовый доступ к файлам
*/

typedef struct _bfile
{
FILE *file;
uchar mask;
int rack;
int pacifier_counter;
} BFILE;


#define PACIFIER_COUNT 2047


/*---------------------------------------------------------
функции высокого уровня
*/
void print_ratios ( char *input, char *output );
void Arhiv ( FILE *input, BFILE *output );
void DeArhiv ( BFILE *input, FILE *output );
long file_size ( char *name );
void messege_complite ( char *prog_name );
/*---------------------------------------------------------
прочие функции необходимые для работы программы
*/
BFILE *OpenInputBFile ( char *name );
BFILE *OpenOutputBFile ( char *name );
void WriteBit ( BFILE *bfile, int bit );
void WriteBits ( BFILE *bfile, ulong code, int count );
int ReadBit ( BFILE *bfile );
ulong ReadBits ( BFILE *bfile, int bit_count );
void CloseInputBFile ( BFILE *bfile );
void CloseOutputBFile ( BFILE *bfile );

/*---------------------------------------------------------
функции работы с моделью данных для алгоритма лзв
*/

uint find_dictionary_match ( int prefix_code, int character );
uint decode_string ( uint offset, uint code );



char *CompressionName = "LZW 12-bit Coder";
char *Usage = "input file-output file\n\n";

void fatal_error( char *str, ... );

/*-----------------------------------------------------------
головная процедура*.
*/

void main(void)
{
char ch;
char filename_in[256];
char filename_out[256];
int i;

BFILE *output;
FILE *input, *output2;

clrscr();
setbuf( stdout, NULL );
printf("\nPlease chose the procedure:");
printf("\n1.Compress file");
printf("\n2.Decompres file");
printf("\n3. Stop and Exit!=)");
printf("\nEnter your choyse: ");
ch=_getche();
switch (ch)
{
case '1':
{
for(i=0;i<256;i++)
{
filename_in[i]=filename_out[i]=NULL;
}
printf("\nEnter name of input file: ");
gets(filename_in);
input = fopen( filename_in, "rb" );
if ( input == NULL )
fatal_error( "Error to open %s for input\n", filename_in);

printf("\nEnter name of output file: ");
gets(filename_out);
output = OpenOutputBFile( filename_out);
if ( output == NULL )
fatal_error( "Error to open %s for output\n", filename_out);

printf( "\nPlease wait-Compresing... %s in %s\n", filename_in, filename_out );
printf( "Using %s\n", CompressionName );
Arhiv( input, output );
CloseOutputBFile( output );
fclose( input );
print_ratios( filename_in, filename_out );
}
break;
case '2':
{
for(i=0;i<256;i++)
{
filename_in[i]=filename_out[i]=NULL;
}
printf("\nEnter name of input file: ");
gets(filename_in);
output = OpenInputBFile( filename_in);
if ( output == NULL )
fatal_error( "Error to open %s for input\n", filename_in);

printf("\nEnter name of output file: ");
gets(filename_out);
output2 = fopen( filename_out, "wb");
if ( output2 == NULL )
fatal_error( "Error to open %s for output\n", filename_out);

printf( "\nPlease wait-Decompresing... %s in %s\n", filename_in, filename_out );
printf( "Using %s\n", CompressionName );
//ExpandFile( output, output2 ); ***** НИГДЕ НЕ ОБЪЯВЛЕНА ЭТА ФУНКЦИЯ *****
CloseOutputBFile( output );
fclose( output2 );
print_ratios( filename_in, filename_out );
}
break;
case '3':
{
}break;
}

_getch();

}

/*-----------------------------------------------------------
обработка фатальной ошибки при работе программы.
*/

void fatal_error( char *str, ... )
{
printf( "Fatal Error: %s\n", str );
exit(1);
}

/*-----------------------------------------------------------
открытие файла для побитовой записи
*/

BFILE *OpenOutputBFile ( char * name )
{
BFILE *bfile;

bfile = (BFILE *) calloc( 1, sizeof( BFILE ) );
bfile->file = fopen( name, "wb" );
bfile->rack = 0;
bfile->mask = 0x80;
bfile->pacifier_counter = 0;
return bfile;
}

/*-----------------------------------------------------------
открытие файла для побитового чтения
*/

BFILE *OpenInputBFile( char *name )
{
BFILE *bfile;

bfile = (BFILE *) calloc( 1, sizeof( BFILE ) );
bfile->file = fopen( name, "rb" );
bfile->rack = 0;
bfile->mask = 0x80;
bfile->pacifier_counter = 0;
return bfile;
}

/*-----------------------------------------------------------
закрытие файла для побитовой записи
*/

void CloseOutputBFile ( BFILE *bfile )
{
if ( bfile->mask != 0x80 )
putc( bfile->rack, bfile->file );
fclose ( bfile->file );
free ( (char *) bfile );
}

/*-----------------------------------------------------------
закрытие файла для опбитового чтения
*/

void CloseInputBFile ( BFILE *bfile )
{
fclose ( bfile->file );
free ( (char *) bfile );
}

/*-----------------------------------------------------------
вывод одного бита*
*/

void WriteBit ( BFILE *bfile, int bit )
{
if ( bit )
bfile->rack |= bfile->mask;
bfile->mask >>= 1;
if ( bfile->mask == 0 )
{
putc( bfile->rack, bfile->file );
if ( ( bfile->pacifier_counter++ & PACIFIER_COUNT ) == 0 )
putc( '.', stdout );
bfile->rack = 0;
bfile->mask = 0x80;
}
}

/*-----------------------------------------------------------
вывод нескольких битов
*/

void WriteBits( BFILE *bfile, ulong code, int count )
{
ulong mask;

mask = 1L << ( count - 1 );
while ( mask != 0)
{
if ( mask & code )
bfile->rack |= bfile->mask;
bfile->mask >>= 1;
if ( bfile->mask == 0 )
{
putc( bfile->rack, bfile->file );
if ( ( bfile->pacifier_counter++ & PACIFIER_COUNT ) == 0 )
putc( '.', stdout );
bfile->rack = 0;
bfile->mask = 0x80;
}
mask >>= 1;
}
}

/*-----------------------------------------------------------
‚Ввод дного бита
*/

int ReadBit( BFILE *bfile )
{
int value;

if ( bfile->mask == 0x80 )
{
bfile->rack = getc( bfile->file );
if ( bfile->rack == EOF )
fatal_error( "Error in procedure ReadBit! Something wrong, chek it!\n" );
if ( ( bfile->pacifier_counter++ & PACIFIER_COUNT ) == 0 )
putc( '.', stdout );
}

value = bfile->rack & bfile->mask;
bfile->mask >>= 1;
if ( bfile->mask == 0 )
bfile->mask = 0x80;
return ( value ? 1 : 0 );
}

/*-----------------------------------------------------------
ввод нескольких битов
*/

ulong ReadBits ( BFILE *bfile, int bit_count )
{
ulong mask;
ulong return_value;

mask = 1L << ( bit_count - 1 );
return_value = 0;
while ( mask != 0 )
{
if ( bfile->mask == 0x80 )
{
bfile->rack = getc( bfile->file );
if ( bfile->rack == EOF )
fatal_error( "Error in procedure ReadBits (not ReadBit)! Something wrong, chek it!\n" );
if ( ( bfile->pacifier_counter++ & PACIFIER_COUNT ) == 0 )
putc( '.', stdout );
}
if ( bfile->rack & bfile->mask )
return_value |= mask;
mask >>= 1;
bfile->mask >>= 1;
if ( bfile->mask == 0 )
bfile->mask = 0x80;
}

return return_value;
}


/*-----------------------------------------------------------
вывод сообщения об использовании
*/

void messege_complite ( char *prog_name )
{
char *short_name;
char *extension;

short_name = strrchr( prog_name, '\\' );
if ( short_name == NULL )
short_name = strrchr( prog_name, '/' );
if ( short_name == NULL )
short_name = strrchr( prog_name, ':' );
if ( short_name != NULL )
short_name++;
else
short_name = prog_name;
extension = strrchr( short_name, '.' );
if ( extension != NULL )
*extension = '\0';
printf( "\nUsing: %s %s\n", short_name, Usage );
exit( 0 );
}

/*-----------------------------------------------------------
измерение длинны файла
*/

long file_size ( char *name )
{
long eof_ftell;
FILE *file;

file = fopen( name, "r" );
if ( file == NULL )
return( 0L );
fseek( file, 0L, SEEK_END );
eof_ftell = ftell( file );
fclose( file );
return eof_ftell;
}

/*-----------------------------------------------------------
вывод сообщения о соотношении размеров файлов
*/
void print_ratios( char *input, char *output )
{
long input_size;
long output_size;
int ratio;

input_size = file_size( input );
if ( input_size == 0 )
input_size = 1;
output_size = file_size( output );
ratio = 100 - (int) ( output_size * 100L / input_size );
printf( "\nByte in: %ld\n", input_size );
printf( "Byte out: %ld\n", output_size );
if ( output_size == 0 )
output_size = 1;
printf( "Compression degree: %d%%\n", ratio );
}

/*-----------------------------------------------------------
„Алгоритм ЛЗВ:
*/

/* ‘структура словаря */

struct dictionary
{
int code_value;
int prefix_code;
char character;
}
dict[TABLE_SIZE];

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

char decode_stack[TABLE_SIZE];

/*-----------------------------------------------------------
сжатие файла:
*/

void Arhiv ( FILE *input, BFILE *output )
{
int next_code, character, string_code;
uint index, i;

/* инициализация */
next_code = FIRST_CODE;
for ( i = 0 ; i < TABLE_SIZE ; i++ )
dict[i].code_value = UNUSED;
/* ‘считать первый символ */
if ( ( string_code = getc( input ) ) == EOF )
string_code = END_OF_STREAM;
/* пока не конец сообщения */
while ( ( character = getc( input ) ) != EOF )
{
/* попытка найти в словаре фразу <фраза*, символ> */
index = find_dictionary_match ( string_code, character );
/* соответствие найдено*/
if ( dict[index].code_value != -1 )
string_code = dict[index].code_value;
/* ’такой пары в словаре нет */
else
{
/* „добавление в словарь */
if ( next_code <= MAX_CODE )
{
dict[index].code_value = next_code++;
dict[index].prefix_code = string_code;
dict[index].character = (char) character;
}
/* выдача кода */
WriteBits( output, (ulong) string_code, BITS );
string_code = character;
}
}
/* завершение кодирования */
WriteBits( output, (ulong) string_code, BITS );
WriteBits( output, (ulong) END_OF_STREAM, BITS );
}

/*-----------------------------------------------------------
извлечение сжатого фала (декодирование)
*/

void DeArhiv( BFILE *input, FILE *output )
{
uint next_code, new_code, old_code;
int character;
uint count;

next_code = FIRST_CODE;
old_code = (uint) ReadBits( input, BITS );
if ( old_code == END_OF_STREAM )
return;
character = old_code;

putc ( old_code, output );

while ( ( new_code = (uint) ReadBits( input, BITS ) )
!= END_OF_STREAM )
{
/* обработка неожиданной ситуации */
if ( new_code >= next_code )
{
decode_stack[ 0 ] = (char) character;
count = decode_string( 1, old_code );
}
else
count = decode_string( 0, new_code );

character = decode_stack[ count - 1 ];
/* выдача раскодированной строки */
while ( count > 0 )
putc( decode_stack[--count], output );
/* обновление словаря */
if ( next_code <= MAX_CODE )
{
dict[next_code].prefix_code = old_code;
dict[next_code].character = (char) character;
next_code++;
}
old_code = new_code;
}
}

/*-----------------------------------------------------------
процедура поиска в словаре указанной пары (код фразы, символ).
используеться хеш, получаемый из параметров
*/

uint find_dictionary_match ( int prefix_code, int character )
{
int index;
int offset;

/* получение значения хеш функции */
index = ( character << ( BITS - 8 ) ) ^ prefix_code;
/* разрешение возможных коллизий
Коллизией хеш-функции H называется два различных входных блока данных x и y таких, что H(x) = H(y).

Коллизии существуют для большинства хеш-функций, но для «хороших» хеш-функций частота их возникновения близка к теоретическому минимуму.
В некоторых частных случаях, когда множество различных входных данных конечно, можно задать инъективную хеш-функцию, по определению не
имеющую коллизий. Однако, для функций, принимающих вход переменной длины и возвращающих хеш постоянной длины (такие, как MD5), коллизии
обязаны существовать, поскольку хотя бы для одного значения хеш-функции соответствующее ему множество входных данных будет бесконечно —
и любые два набора данных из этого множества образуют коллизию. */
if ( index == 0 )

offset = 1;
else
offset = TABLE_SIZE - index;
for ( ; ; )
{
/* ячейка словаря не использована*** */
if ( dict[index].code_value == UNUSED )
return index;
/* найдено соответствие */
if ( dict[index].prefix_code == prefix_code &&
dict[index].character == (char) character )
return index;
/* коллизия.. попытка ее разрешения */
index -= offset;
if ( index < 0 )
index += TABLE_SIZE;
}
}

/*-----------------------------------------------------------
декодирование тсроки. процедура размещает символы в стеке, возвращая их количество
*/

uint decode_string ( uint count, uint kod )
{
while ( kod > 255 ) /*пока не встретитсья код символа* */
{
decode_stack[count++] = dict[kod].character;
kod = dict[kod].prefix_code;
}
decode_stack[count++] = (char) kod;
return count;
}


148 строка:
ExpandFile( output, output2 );
Нигде не определена эта функция, и нигде не написано что она должна делать, поэтому я её закомментировал.
а так

1>------ Build started: Project: asfasfd, Configuration: Debug Win32 ------
1>Compiling...
1>asfasfd.cpp
1>Build log was saved at "file://d:\Projects\asfasfd\asfasfd\Debug\BuildLog.htm"
1>asfasfd - 0 error(s), 0 warning(s)
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

mephistophel
26-04-2010, 20:58
спасибо большое




© OSzone.net 2001-2012