skuska
This commit is contained in:
parent
790aa2149c
commit
ee7833a8f1
@ -123,7 +123,7 @@ void write_bits(FILE* file, const char* bits, unsigned char* buffer, int* bit_po
|
|||||||
(*bit_pos)++;
|
(*bit_pos)++;
|
||||||
if (*bit_pos % 8 == 0) {
|
if (*bit_pos % 8 == 0) {
|
||||||
fwrite(buffer, 1, 1, file);
|
fwrite(buffer, 1, 1, file);
|
||||||
buffer[*bit_pos / 8 - 1] = 0; // Clear the written byte
|
buffer[*bit_pos / 8 - 1] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -142,14 +142,14 @@ HuffmanNode* deserialize_tree(FILE* file) {
|
|||||||
if (marker == EOF) return NULL;
|
if (marker == EOF) return NULL;
|
||||||
|
|
||||||
if (marker == '1') {
|
if (marker == '1') {
|
||||||
// Leaf node: Read the symbol
|
|
||||||
HuffmanNode* node = (HuffmanNode*)malloc(sizeof(HuffmanNode));
|
HuffmanNode* node = (HuffmanNode*)malloc(sizeof(HuffmanNode));
|
||||||
node->symbol = fgetc(file);
|
node->symbol = fgetc(file);
|
||||||
node->left = node->right = NULL;
|
node->left = node->right = NULL;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal node: Create a new node and deserialize children
|
|
||||||
HuffmanNode* node = (HuffmanNode*)malloc(sizeof(HuffmanNode));
|
HuffmanNode* node = (HuffmanNode*)malloc(sizeof(HuffmanNode));
|
||||||
node->left = deserialize_tree(file);
|
node->left = deserialize_tree(file);
|
||||||
node->right = deserialize_tree(file);
|
node->right = deserialize_tree(file);
|
||||||
@ -162,19 +162,17 @@ int compress_1(const char* input_file_name, const char* output_file_name) {
|
|||||||
unsigned char* data = read_file(input_file_name, &size);
|
unsigned char* data = read_file(input_file_name, &size);
|
||||||
if (!data) return -1;
|
if (!data) return -1;
|
||||||
|
|
||||||
// Build Huffman tree
|
|
||||||
HuffmanNode* root = build_huffman_tree(data, size);
|
HuffmanNode* root = build_huffman_tree(data, size);
|
||||||
if (!root) {
|
if (!root) {
|
||||||
free(data);
|
free(data);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate Huffman codes
|
|
||||||
char* codes[256] = {0};
|
char* codes[256] = {0};
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
generate_huffman_codes(root, codes, buffer, 0);
|
generate_huffman_codes(root, codes, buffer, 0);
|
||||||
|
|
||||||
// Open output file
|
|
||||||
FILE* output_file = fopen(output_file_name, "wb");
|
FILE* output_file = fopen(output_file_name, "wb");
|
||||||
if (!output_file) {
|
if (!output_file) {
|
||||||
perror("Error opening output file");
|
perror("Error opening output file");
|
||||||
@ -183,7 +181,7 @@ int compress_1(const char* input_file_name, const char* output_file_name) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compress data
|
|
||||||
unsigned char bit_buffer[1] = {0};
|
unsigned char bit_buffer[1] = {0};
|
||||||
int bit_pos = 0;
|
int bit_pos = 0;
|
||||||
|
|
||||||
@ -191,7 +189,6 @@ int compress_1(const char* input_file_name, const char* output_file_name) {
|
|||||||
write_bits(output_file, codes[data[i]], bit_buffer, &bit_pos);
|
write_bits(output_file, codes[data[i]], bit_buffer, &bit_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush remaining bits
|
|
||||||
if (bit_pos % 8 != 0) {
|
if (bit_pos % 8 != 0) {
|
||||||
fwrite(bit_buffer, 1, 1, output_file);
|
fwrite(bit_buffer, 1, 1, output_file);
|
||||||
}
|
}
|
||||||
@ -200,7 +197,7 @@ int compress_1(const char* input_file_name, const char* output_file_name) {
|
|||||||
|
|
||||||
printf("Compressing using Huffman coding...\n");
|
printf("Compressing using Huffman coding...\n");
|
||||||
|
|
||||||
// Clean up
|
|
||||||
for (int i = 0; i < 256; i++) {
|
for (int i = 0; i < 256; i++) {
|
||||||
if (codes[i]) free(codes[i]);
|
if (codes[i]) free(codes[i]);
|
||||||
}
|
}
|
||||||
@ -273,15 +270,14 @@ int compress_2(const char* input_file_name, const char* output_file_name) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t search_buffer_size = 1024; // Veľkosť search bufferu
|
size_t search_buffer_size = 1024;
|
||||||
size_t lookahead_buffer_size = 16; // Veľkosť lookahead bufferu
|
size_t lookahead_buffer_size = 16;
|
||||||
|
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
while (pos < size) {
|
while (pos < size) {
|
||||||
size_t best_match_offset = 0;
|
size_t best_match_offset = 0;
|
||||||
size_t best_match_length = 0;
|
size_t best_match_length = 0;
|
||||||
|
|
||||||
// Vyhľadaj najlepšiu zhodu v search bufferi
|
|
||||||
for (size_t i = (pos > search_buffer_size ? pos - search_buffer_size : 0); i < pos; i++) {
|
for (size_t i = (pos > search_buffer_size ? pos - search_buffer_size : 0); i < pos; i++) {
|
||||||
size_t match_length = 0;
|
size_t match_length = 0;
|
||||||
while (match_length < lookahead_buffer_size &&
|
while (match_length < lookahead_buffer_size &&
|
||||||
@ -295,7 +291,6 @@ int compress_2(const char* input_file_name, const char* output_file_name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ulož trojicu (offset, length, next_symbol)
|
|
||||||
unsigned char offset_high = (best_match_offset >> 8) & 0xFF;
|
unsigned char offset_high = (best_match_offset >> 8) & 0xFF;
|
||||||
unsigned char offset_low = best_match_offset & 0xFF;
|
unsigned char offset_low = best_match_offset & 0xFF;
|
||||||
unsigned char length = best_match_length;
|
unsigned char length = best_match_length;
|
||||||
@ -306,7 +301,6 @@ int compress_2(const char* input_file_name, const char* output_file_name) {
|
|||||||
fputc(length, output_file);
|
fputc(length, output_file);
|
||||||
fputc(next_symbol, output_file);
|
fputc(next_symbol, output_file);
|
||||||
|
|
||||||
// Posuň pozíciu v dátach
|
|
||||||
pos += best_match_length + 1;
|
pos += best_match_length + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -351,13 +345,13 @@ int decompress_2(const char* input_file_name, const char* output_file_name) {
|
|||||||
|
|
||||||
size_t offset = (offset_high << 8) | offset_low;
|
size_t offset = (offset_high << 8) | offset_low;
|
||||||
|
|
||||||
// Skopíruj zhodu z histórie
|
|
||||||
for (size_t i = 0; i < length; i++) {
|
for (size_t i = 0; i < length; i++) {
|
||||||
output_buffer[pos] = output_buffer[pos - offset];
|
output_buffer[pos] = output_buffer[pos - offset];
|
||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pridaj ďalší symbol
|
|
||||||
output_buffer[pos++] = next_symbol;
|
output_buffer[pos++] = next_symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user