1 v 1 sk1
This commit is contained in:
parent
46a15ce65a
commit
1f566ebe0f
@ -3,6 +3,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#define WINDOW_SIZE 4096 // Размер скользящего окна
|
#define WINDOW_SIZE 4096 // Размер скользящего окна
|
||||||
#define LOOKAHEAD_BUFFER_SIZE 15 // Размер буфера предпросмотра
|
#define LOOKAHEAD_BUFFER_SIZE 15 // Размер буфера предпросмотра
|
||||||
@ -150,11 +151,15 @@ void free_tree(Node* root)
|
|||||||
int compress_2(const char* input_file_name, const char* output_file_name)
|
int compress_2(const char* input_file_name, const char* output_file_name)
|
||||||
{
|
{
|
||||||
FILE* input = fopen(input_file_name, "rb");
|
FILE* input = fopen(input_file_name, "rb");
|
||||||
if (!input) return -1;
|
if (!input)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int freq[MAX_TREE_NODES] = {0};
|
int freq[MAX_TREE_NODES] = {0};
|
||||||
unsigned char buffer;
|
unsigned char buffer;
|
||||||
|
|
||||||
|
// Читаем файл и подсчитываем частоты символов
|
||||||
while (fread(&buffer, 1, 1, input))
|
while (fread(&buffer, 1, 1, input))
|
||||||
{
|
{
|
||||||
freq[buffer]++;
|
freq[buffer]++;
|
||||||
@ -175,7 +180,9 @@ int compress_2(const char* input_file_name, const char* output_file_name)
|
|||||||
char code[MAX_TREE_NODES];
|
char code[MAX_TREE_NODES];
|
||||||
build_codes(heap->nodes[0], code, 0, codes);
|
build_codes(heap->nodes[0], code, 0, codes);
|
||||||
|
|
||||||
|
// Вернемся в начало входного файла
|
||||||
fseek(input, 0, SEEK_SET);
|
fseek(input, 0, SEEK_SET);
|
||||||
|
|
||||||
FILE* output = fopen(output_file_name, "wb");
|
FILE* output = fopen(output_file_name, "wb");
|
||||||
if (!output)
|
if (!output)
|
||||||
{
|
{
|
||||||
@ -183,14 +190,17 @@ int compress_2(const char* input_file_name, const char* output_file_name)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Записываем частоты символов
|
||||||
fwrite(freq, sizeof(freq), 1, output);
|
fwrite(freq, sizeof(freq), 1, output);
|
||||||
|
|
||||||
unsigned char out_buffer = 0;
|
unsigned char out_buffer = 0;
|
||||||
int bit_count = 0;
|
int bit_count = 0;
|
||||||
|
|
||||||
|
// Записываем закодированные данные
|
||||||
while (fread(&buffer, 1, 1, input))
|
while (fread(&buffer, 1, 1, input))
|
||||||
{
|
{
|
||||||
char* symbol_code = codes[buffer];
|
char* symbol_code = codes[buffer];
|
||||||
|
|
||||||
for (int i = 0; symbol_code[i] != '\0'; i++)
|
for (int i = 0; symbol_code[i] != '\0'; i++)
|
||||||
{
|
{
|
||||||
out_buffer <<= 1;
|
out_buffer <<= 1;
|
||||||
@ -215,6 +225,13 @@ int compress_2(const char* input_file_name, const char* output_file_name)
|
|||||||
fwrite(&out_buffer, 1, 1, output);
|
fwrite(&out_buffer, 1, 1, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fseek(input, 0, SEEK_END);
|
||||||
|
long sizeIN = ftell(input);
|
||||||
|
fseek(input, 0, SEEK_SET);
|
||||||
|
|
||||||
|
// Записываем реальный размер входного файла для декомпрессии
|
||||||
|
fwrite(&sizeIN, sizeof(sizeIN), 1, output);
|
||||||
|
|
||||||
fseek(output, 0, SEEK_END);
|
fseek(output, 0, SEEK_END);
|
||||||
int sizeOUT = ftell(output);
|
int sizeOUT = ftell(output);
|
||||||
fseek(output, 0, SEEK_SET);
|
fseek(output, 0, SEEK_SET);
|
||||||
@ -230,7 +247,10 @@ int compress_2(const char* input_file_name, const char* output_file_name)
|
|||||||
int decompress_2(const char* input_file_name, const char* output_file_name)
|
int decompress_2(const char* input_file_name, const char* output_file_name)
|
||||||
{
|
{
|
||||||
FILE* input = fopen(input_file_name, "rb");
|
FILE* input = fopen(input_file_name, "rb");
|
||||||
if (!input) return -1;
|
if (!input)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int freq[MAX_TREE_NODES];
|
int freq[MAX_TREE_NODES];
|
||||||
fread(freq, sizeof(freq), 1, input);
|
fread(freq, sizeof(freq), 1, input);
|
||||||
@ -250,30 +270,55 @@ int decompress_2(const char* input_file_name, const char* output_file_name)
|
|||||||
if (!output)
|
if (!output)
|
||||||
{
|
{
|
||||||
fclose(input);
|
fclose(input);
|
||||||
|
free_tree(heap->nodes[0]);
|
||||||
|
free(heap);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* root = heap->nodes[0];
|
Node* root = heap->nodes[0];
|
||||||
Node* current = root;
|
Node* current = root;
|
||||||
unsigned char buffer;
|
|
||||||
|
|
||||||
while (fread(&buffer, 1, 1, input))
|
// Перемещаемся к концу файла, чтобы прочитать оригинальный размер
|
||||||
|
fseek(input, -sizeof(long), SEEK_END);
|
||||||
|
long original_size;
|
||||||
|
fread(&original_size, sizeof(long), 1, input);
|
||||||
|
|
||||||
|
// Вернемся к началу сжатых данных
|
||||||
|
long data_end = ftell(input) - sizeof(long);
|
||||||
|
fseek(input, sizeof(freq), SEEK_SET);
|
||||||
|
|
||||||
|
long written_bytes = 0;
|
||||||
|
unsigned char buffer;
|
||||||
|
int bit_count = 0;
|
||||||
|
|
||||||
|
while (ftell(input) < data_end || (bit_count > 0 && written_bytes < original_size))
|
||||||
{
|
{
|
||||||
for (int i = 7; i >= 0; i--)
|
if (bit_count == 0 && fread(&buffer, 1, 1, input) == 1)
|
||||||
{
|
{
|
||||||
if ((buffer >> i) & 1)
|
bit_count = 8;
|
||||||
{
|
|
||||||
current = current->right;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (bit_count > 0)
|
||||||
{
|
{
|
||||||
current = current->left;
|
int bit = (buffer >> (bit_count - 1)) & 1;
|
||||||
}
|
bit_count--;
|
||||||
|
|
||||||
|
current = bit ? current->right : current->left;
|
||||||
|
|
||||||
if (!current->left && !current->right)
|
if (!current->left && !current->right)
|
||||||
|
{
|
||||||
|
if (written_bytes < original_size)
|
||||||
{
|
{
|
||||||
fwrite(¤t->symbol, 1, 1, output);
|
fwrite(¤t->symbol, 1, 1, output);
|
||||||
|
written_bytes++;
|
||||||
|
}
|
||||||
current = root;
|
current = root;
|
||||||
|
|
||||||
|
// Остановимся, если записали все байты
|
||||||
|
if (written_bytes == original_size)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -290,6 +335,10 @@ int decompress_2(const char* input_file_name, const char* output_file_name)
|
|||||||
return sizeOUT;
|
return sizeOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Функция для записи токена в файл в компактном формате
|
// Функция для записи токена в файл в компактном формате
|
||||||
void write_token(FILE *file, LZ77Token token)
|
void write_token(FILE *file, LZ77Token token)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user