skuska2
This commit is contained in:
		
							parent
							
								
									8682cad5c2
								
							
						
					
					
						commit
						0f9977f603
					
				
							
								
								
									
										236
									
								
								sk1/compressor.c
									
									
									
									
									
								
							
							
						
						
									
										236
									
								
								sk1/compressor.c
									
									
									
									
									
								
							| @ -1,66 +1,71 @@ | |||||||
| #include "compressor.h" | #include "compressor.h" // Hlavičkový súbor, ktorý obsahuje deklarácie funkcií a štruktúr používaných na kompresiu a dekompresiu. | ||||||
| #include <stdio.h> | #include <stdio.h>      // Knižnica pre prácu so vstupom a výstupom. | ||||||
| #include <stdlib.h> | #include <stdlib.h>     // Knižnica pre alokáciu pamäte a ďalšie základné funkcie. | ||||||
| #include <string.h> | #include <string.h>     // Knižnica pre prácu s reťazcami. | ||||||
| 
 | 
 | ||||||
|  | // Funkcia na čítanie obsahu súboru do pamäte.
 | ||||||
| unsigned char* read_file(const char* file_name, size_t* size) { | unsigned char* read_file(const char* file_name, size_t* size) { | ||||||
|     FILE* file = fopen(file_name, "rb"); |     FILE* file = fopen(file_name, "rb"); // Otvorenie súboru v režime čítania binárnych dát.
 | ||||||
|     if (!file) { |     if (!file) { | ||||||
|         perror("Error opening file"); |         perror("Error opening file"); // Chybové hlásenie, ak sa súbor nedá otvoriť.
 | ||||||
|         return NULL; |         return NULL; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fseek(file, 0, SEEK_END); |     fseek(file, 0, SEEK_END);  // Posun ukazovateľa na koniec súboru.
 | ||||||
|     *size = ftell(file); |     *size = ftell(file);       // Zistenie veľkosti súboru.
 | ||||||
|     rewind(file); |     rewind(file);              // Návrat ukazovateľa na začiatok súboru.
 | ||||||
| 
 | 
 | ||||||
|     unsigned char* buffer = (unsigned char*)malloc(*size); |     unsigned char* buffer = (unsigned char*)malloc(*size); // Alokácia pamäte pre obsah súboru.
 | ||||||
|     if (!buffer) { |     if (!buffer) { | ||||||
|         perror("Memory allocation error"); |         perror("Memory allocation error"); // Chybové hlásenie, ak sa nepodarí alokovať pamäť.
 | ||||||
|         fclose(file); |         fclose(file); | ||||||
|         return NULL; |         return NULL; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fread(buffer, 1, *size, file); |     fread(buffer, 1, *size, file); // Načítanie obsahu súboru do bufferu.
 | ||||||
|     fclose(file); |     fclose(file); | ||||||
|     return buffer; |     return buffer; // Návrat ukazovateľa na buffer.
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Funkcia na zápis obsahu z pamäte do súboru.
 | ||||||
| int write_file(const char* file_name, const unsigned char* buffer, size_t size) { | int write_file(const char* file_name, const unsigned char* buffer, size_t size) { | ||||||
|     FILE* file = fopen(file_name, "wb"); |     FILE* file = fopen(file_name, "wb"); // Otvorenie súboru v režime zápisu binárnych dát.
 | ||||||
|     if (!file) { |     if (!file) { | ||||||
|         perror("Error opening file"); |         perror("Error opening file"); | ||||||
|         return -1; |         return -1; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fwrite(buffer, 1, size, file); |     fwrite(buffer, 1, size, file); // Zápis dát do súboru.
 | ||||||
|     fclose(file); |     fclose(file); | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Funkcia na vytvorenie Huffmanovho stromu z daných dát.
 | ||||||
| HuffmanNode* build_huffman_tree(const unsigned char* data, size_t size) { | HuffmanNode* build_huffman_tree(const unsigned char* data, size_t size) { | ||||||
|     size_t frequencies[256] = {0}; |     size_t frequencies[256] = {0}; // Pole na počítanie frekvencie každého znaku.
 | ||||||
| 
 | 
 | ||||||
|     for (size_t i = 0; i < size; i++) { |     for (size_t i = 0; i < size; i++) { | ||||||
|         frequencies[data[i]]++; |         frequencies[data[i]]++; // Zvýšenie frekvencie pre daný znak.
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     HuffmanNode* nodes[256]; |     HuffmanNode* nodes[256]; // Pole uzlov Huffmanovho stromu.
 | ||||||
|     int node_count = 0; |     int node_count = 0; | ||||||
| 
 | 
 | ||||||
|  |     // Vytvorenie listových uzlov pre znaky s nenulovou frekvenciou.
 | ||||||
|     for (int i = 0; i < 256; i++) { |     for (int i = 0; i < 256; i++) { | ||||||
|         if (frequencies[i] > 0) { |         if (frequencies[i] > 0) { | ||||||
|             HuffmanNode* node = (HuffmanNode*)malloc(sizeof(HuffmanNode)); |             HuffmanNode* node = (HuffmanNode*)malloc(sizeof(HuffmanNode)); | ||||||
|             node->symbol = (unsigned char)i; |             node->symbol = (unsigned char)i; // Znak reprezentovaný uzlom.
 | ||||||
|             node->frequency = frequencies[i]; |             node->frequency = frequencies[i]; // Frekvencia znaku.
 | ||||||
|             node->left = NULL; |             node->left = NULL; | ||||||
|             node->right = NULL; |             node->right = NULL; | ||||||
|             nodes[node_count++] = node; |             nodes[node_count++] = node; // Pridanie uzla do zoznamu.
 | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     // Opakované zlúčenie dvoch uzlov s najnižšou frekvenciou.
 | ||||||
|     while (node_count > 1) { |     while (node_count > 1) { | ||||||
| 
 |         // Vyhľadanie dvoch uzlov s najnižšou frekvenciou.
 | ||||||
|         int min1 = 0, min2 = 1; |         int min1 = 0, min2 = 1; | ||||||
|         if (nodes[min2]->frequency < nodes[min1]->frequency) { |         if (nodes[min2]->frequency < nodes[min1]->frequency) { | ||||||
|             min1 = 1; |             min1 = 1; | ||||||
| @ -76,104 +81,111 @@ HuffmanNode* build_huffman_tree(const unsigned char* data, size_t size) { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         // Vytvorenie nového rodičovského uzla.
 | ||||||
|         HuffmanNode* new_node = (HuffmanNode*)malloc(sizeof(HuffmanNode)); |         HuffmanNode* new_node = (HuffmanNode*)malloc(sizeof(HuffmanNode)); | ||||||
|         new_node->symbol = 0; |         new_node->symbol = 0; // Symbol je irelevantný pre vnútorné uzly.
 | ||||||
|         new_node->frequency = nodes[min1]->frequency + nodes[min2]->frequency; |         new_node->frequency = nodes[min1]->frequency + nodes[min2]->frequency; | ||||||
|         new_node->left = nodes[min1]; |         new_node->left = nodes[min1]; | ||||||
|         new_node->right = nodes[min2]; |         new_node->right = nodes[min2]; | ||||||
| 
 | 
 | ||||||
|  |         // Aktualizácia zoznamu uzlov.
 | ||||||
|         nodes[min1] = new_node; |         nodes[min1] = new_node; | ||||||
|         nodes[min2] = nodes[node_count - 1]; |         nodes[min2] = nodes[node_count - 1]; | ||||||
|         node_count--; |         node_count--; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return nodes[0]; |     return nodes[0]; // Návrat koreňa Huffmanovho stromu.
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | // Rekurzívna funkcia na generovanie Huffmanových kódov pre každý znak.
 | ||||||
| void generate_huffman_codes(HuffmanNode* root, char** codes, char* buffer, int depth) { | void generate_huffman_codes(HuffmanNode* root, char** codes, char* buffer, int depth) { | ||||||
|     if (!root->left && !root->right) { |     if (!root->left && !root->right) { // Ak uzol nemá potomkov, je to listový uzol.
 | ||||||
|         buffer[depth] = '\0'; |         buffer[depth] = '\0'; // Ukončenie reťazca.
 | ||||||
|         codes[root->symbol] = strdup(buffer); |         codes[root->symbol] = strdup(buffer); // Uloženie kódu pre znak.
 | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (root->left) { |     if (root->left) { | ||||||
|         buffer[depth] = '0'; |         buffer[depth] = '0'; // Pridanie '0' pre cestu doľava.
 | ||||||
|         generate_huffman_codes(root->left, codes, buffer, depth + 1); |         generate_huffman_codes(root->left, codes, buffer, depth + 1); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (root->right) { |     if (root->right) { | ||||||
|         buffer[depth] = '1'; |         buffer[depth] = '1'; // Pridanie '1' pre cestu doprava.
 | ||||||
|         generate_huffman_codes(root->right, codes, buffer, depth + 1); |         generate_huffman_codes(root->right, codes, buffer, depth + 1); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Funkcia na uvoľnenie pamäte alokovanej pre Huffmanov strom.
 | ||||||
| void free_huffman_tree(HuffmanNode* root) { | void free_huffman_tree(HuffmanNode* root) { | ||||||
|     if (!root) return; |     if (!root) return; // Ak je strom prázdny, nič nerobí.
 | ||||||
|     free_huffman_tree(root->left); |     free_huffman_tree(root->left);  // Rekurzívne uvoľnenie ľavého podstromu.
 | ||||||
|     free_huffman_tree(root->right); |     free_huffman_tree(root->right); // Rekurzívne uvoľnenie pravého podstromu.
 | ||||||
|     free(root); |     free(root); // Uvoľnenie aktuálneho uzla.
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Funkcia na zápis bitov do súboru pomocou dočasného bufferu.
 | ||||||
| void write_bits(FILE* file, const char* bits, unsigned char* buffer, int* bit_pos) { | void write_bits(FILE* file, const char* bits, unsigned char* buffer, int* bit_pos) { | ||||||
|     for (int i = 0; bits[i] != '\0'; i++) { |     for (int i = 0; bits[i] != '\0'; i++) { // Prechádza všetky bity v reťazci.
 | ||||||
|         if (bits[i] == '1') { |         if (bits[i] == '1') { // Ak je bit '1', nastaví príslušný bit v bufferi.
 | ||||||
|             buffer[*bit_pos / 8] |= (1 << (7 - (*bit_pos % 8))); |             buffer[*bit_pos / 8] |= (1 << (7 - (*bit_pos % 8))); | ||||||
|         } |         } | ||||||
|         (*bit_pos)++; |         (*bit_pos)++; // Posunie sa na ďalšiu bitovú pozíciu.
 | ||||||
|         if (*bit_pos % 8 == 0) { | 
 | ||||||
|  |         if (*bit_pos % 8 == 0) { // Ak je buffer plný (8 bitov), zapíše sa do súboru.
 | ||||||
|             fwrite(buffer, 1, 1, file); |             fwrite(buffer, 1, 1, file); | ||||||
|             buffer[*bit_pos / 8 - 1] = 0; |             buffer[*bit_pos / 8 - 1] = 0; // Vyprázdni buffer.
 | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Funkcia na čítanie jedného bitu zo súboru.
 | ||||||
| int read_bit(FILE* file, unsigned char* buffer, int* bit_pos) { | int read_bit(FILE* file, unsigned char* buffer, int* bit_pos) { | ||||||
|     if (*bit_pos % 8 == 0) { |     if (*bit_pos % 8 == 0) { // Ak sa číta nový bajt, načíta ho do bufferu.
 | ||||||
|         if (fread(buffer, 1, 1, file) != 1) return -1;  |         if (fread(buffer, 1, 1, file) != 1) return -1; // Ak sa nedá čítať, vráti chybu.
 | ||||||
|     } |     } | ||||||
|     int bit = (*buffer >> (7 - (*bit_pos % 8))) & 1; |     int bit = (*buffer >> (7 - (*bit_pos % 8))) & 1; // Získa hodnotu aktuálneho bitu.
 | ||||||
|     (*bit_pos)++; |     (*bit_pos)++; // Posunie sa na ďalšiu bitovú pozíciu.
 | ||||||
|     return bit; |     return bit; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Funkcia na deserializáciu Huffmanovho stromu zo súboru.
 | ||||||
| HuffmanNode* deserialize_tree(FILE* file) { | HuffmanNode* deserialize_tree(FILE* file) { | ||||||
|     int marker = fgetc(file); |     int marker = fgetc(file); // Prečíta znak z binárneho súboru.
 | ||||||
|     if (marker == EOF) return NULL; |     if (marker == EOF) return NULL; // Ak je súbor na konci, vráti NULL.
 | ||||||
| 
 |  | ||||||
|     if (marker == '1') { |  | ||||||
| 
 | 
 | ||||||
|  |     if (marker == '1') { // Ak je marker '1', ide o listový uzol.
 | ||||||
|         HuffmanNode* node = (HuffmanNode*)malloc(sizeof(HuffmanNode)); |         HuffmanNode* node = (HuffmanNode*)malloc(sizeof(HuffmanNode)); | ||||||
|         node->symbol = fgetc(file); |         node->symbol = fgetc(file); // Prečíta znak listového uzla.
 | ||||||
|         node->left = node->right = NULL; |         node->left = node->right = NULL; | ||||||
|         return node; |         return node; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 |     // Ak je marker '0', ide o vnútorný uzol. Rekurzívne načíta podstromy.
 | ||||||
|     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); | ||||||
|     return node; |     return node; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | // Funkcia na kompresiu súboru pomocou Huffmanovho kódovania.
 | ||||||
| int compress_1(const char* input_file_name, const char* output_file_name) { | int compress_1(const char* input_file_name, const char* output_file_name) { | ||||||
|     size_t size; |     size_t size; | ||||||
|     unsigned char* data = read_file(input_file_name, &size); |     unsigned char* data = read_file(input_file_name, &size); // Načítanie vstupného súboru.
 | ||||||
|     if (!data) return -1; |     if (!data) return -1; | ||||||
| 
 | 
 | ||||||
|     HuffmanNode* root = build_huffman_tree(data, size); |     HuffmanNode* root = build_huffman_tree(data, size); // Vytvorenie Huffmanovho stromu.
 | ||||||
|     if (!root) { |     if (!root) { | ||||||
|         free(data); |         free(data); | ||||||
|         return -1; |         return -1; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     char* codes[256] = {0}; |     char* codes[256] = {0}; // Pole na uloženie kódov pre každý znak.
 | ||||||
|     char buffer[256]; |     char buffer[256]; | ||||||
|     generate_huffman_codes(root, codes, buffer, 0); |     generate_huffman_codes(root, codes, buffer, 0); // Generovanie Huffmanových kódov.
 | ||||||
| 
 | 
 | ||||||
| 
 |     FILE* output_file = fopen(output_file_name, "wb"); // Otvorenie výstupného súboru.
 | ||||||
|     FILE* output_file = fopen(output_file_name, "wb"); |  | ||||||
|     if (!output_file) { |     if (!output_file) { | ||||||
|         perror("Error opening output file"); |         perror("Error opening output file"); | ||||||
|         free(data); |         free(data); | ||||||
| @ -181,152 +193,151 @@ int compress_1(const char* input_file_name, const char* output_file_name) { | |||||||
|         return -1; |         return -1; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 |     unsigned char bit_buffer[1] = {0}; // Dočasný buffer na bity.
 | ||||||
|     unsigned char bit_buffer[1] = {0}; |  | ||||||
|     int bit_pos = 0; |     int bit_pos = 0; | ||||||
| 
 | 
 | ||||||
|     for (size_t i = 0; i < size; i++) { |     for (size_t i = 0; i < size; i++) { // Pre každý znak vo vstupnom súbore.
 | ||||||
|         write_bits(output_file, codes[data[i]], bit_buffer, &bit_pos); |         write_bits(output_file, codes[data[i]], bit_buffer, &bit_pos); // Zapíše kód do súboru.
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (bit_pos % 8 != 0) { |     if (bit_pos % 8 != 0) { // Ak buffer nie je prázdny, zapíše sa jeho zvyšok.
 | ||||||
|         fwrite(bit_buffer, 1, 1, output_file); |         fwrite(bit_buffer, 1, 1, output_file); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fclose(output_file); |     fclose(output_file); // Uzavretie výstupného súboru.
 | ||||||
| 
 | 
 | ||||||
|     printf("Compressing using Huffman coding...\n"); |     printf("Compressing using Huffman coding...\n"); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|     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]); // Uvoľnenie pamäte pre kódy.
 | ||||||
|     } |     } | ||||||
|     free_huffman_tree(root); |     free_huffman_tree(root); // Uvoľnenie pamäte pre Huffmanov strom.
 | ||||||
|     free(data); |     free(data); // Uvoľnenie dátového bufferu.
 | ||||||
| 
 | 
 | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | // Funkcia na dekompresiu súboru komprimovaného Huffmanovým kódovaním.
 | ||||||
| int decompress_1(const char* input_file_name, const char* output_file_name) { | int decompress_1(const char* input_file_name, const char* output_file_name) { | ||||||
|     FILE* input_file = fopen(input_file_name, "rb"); |     FILE* input_file = fopen(input_file_name, "rb"); // Otvorenie vstupného súboru v binárnom režime.
 | ||||||
|     if (!input_file) { |     if (!input_file) { | ||||||
|         perror("Error opening input file"); |         perror("Error opening input file"); // Chybové hlásenie, ak sa súbor nedá otvoriť.
 | ||||||
|         return -1; |         return -1; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     FILE* output_file = fopen(output_file_name, "wb"); |     FILE* output_file = fopen(output_file_name, "wb"); // Otvorenie výstupného súboru v binárnom režime.
 | ||||||
|     if (!output_file) { |     if (!output_file) { | ||||||
|         perror("Error opening output file"); |         perror("Error opening output file"); | ||||||
|         fclose(input_file); |         fclose(input_file); | ||||||
|         return -1; |         return -1; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|      |     HuffmanNode* root = deserialize_tree(input_file); // Načítanie Huffmanovho stromu zo súboru.
 | ||||||
|     HuffmanNode* root = deserialize_tree(input_file); |  | ||||||
|     if (!root) { |     if (!root) { | ||||||
|         fclose(input_file); |         fclose(input_file); | ||||||
|         fclose(output_file); |         fclose(output_file); | ||||||
|         return -1; |         return -1; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|      |     unsigned char bit_buffer[1]; // Buffer na čítanie bitov.
 | ||||||
|     unsigned char bit_buffer[1]; |  | ||||||
|     int bit_pos = 0; |     int bit_pos = 0; | ||||||
|     HuffmanNode* current = root; |     HuffmanNode* current = root; // Počiatočný uzol stromu.
 | ||||||
| 
 | 
 | ||||||
|     while (1) { |     while (1) { | ||||||
|         int bit = read_bit(input_file, bit_buffer, &bit_pos); |         int bit = read_bit(input_file, bit_buffer, &bit_pos); // Čítanie bitu zo súboru.
 | ||||||
|         if (bit == -1) break; |         if (bit == -1) break; // Ak je koniec súboru, ukončí sa čítanie.
 | ||||||
| 
 | 
 | ||||||
|         current = (bit == 0) ? current->left : current->right; |         current = (bit == 0) ? current->left : current->right; // Posun v strome na základe bitu.
 | ||||||
| 
 | 
 | ||||||
|         if (!current->left && !current->right) { |         if (!current->left && !current->right) { // Ak je uzol listový, znamená to dekódovaný znak.
 | ||||||
|             fputc(current->symbol, output_file); |             fputc(current->symbol, output_file); // Zapíše sa znak do výstupného súboru.
 | ||||||
|             current = root; |             current = root; // Návrat na koreň stromu pre ďalší znak.
 | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fclose(input_file); |     fclose(input_file); // Uzavretie vstupného súboru.
 | ||||||
|     fclose(output_file); |     fclose(output_file); // Uzavretie výstupného súboru.
 | ||||||
|     free_huffman_tree(root); |     free_huffman_tree(root); // Uvoľnenie pamäte Huffmanovho stromu.
 | ||||||
| 
 | 
 | ||||||
|     printf("Decompressing using Huffman coding...\n"); |     printf("Decompressing using Huffman coding...\n"); | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | // Funkcia na kompresiu súboru pomocou LZ77 algoritmu.
 | ||||||
| 
 |  | ||||||
| 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) { | ||||||
|     size_t size; |     size_t size; | ||||||
|     unsigned char* data = read_file(input_file_name, &size); |     unsigned char* data = read_file(input_file_name, &size); // Načítanie obsahu vstupného súboru.
 | ||||||
|     if (!data) return -1; |     if (!data) return -1; | ||||||
| 
 | 
 | ||||||
|     FILE* output_file = fopen(output_file_name, "wb"); |     FILE* output_file = fopen(output_file_name, "wb"); // Otvorenie výstupného súboru v binárnom režime.
 | ||||||
|     if (!output_file) { |     if (!output_file) { | ||||||
|         perror("Error opening output file"); |         perror("Error opening output file"); | ||||||
|         free(data); |         free(data); | ||||||
|         return -1; |         return -1; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     size_t search_buffer_size = 1024;  |     size_t search_buffer_size = 1024; // Veľkosť vyhľadávacieho okna.
 | ||||||
|     size_t lookahead_buffer_size = 16;  |     size_t lookahead_buffer_size = 16; // Veľkosť prehliadacieho okna.
 | ||||||
| 
 | 
 | ||||||
|     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; // Najlepší posun pre aktuálny segment.
 | ||||||
|         size_t best_match_length = 0; |         size_t best_match_length = 0; // Dĺžka najlepšieho zhody.
 | ||||||
| 
 | 
 | ||||||
|  |         // Vyhľadávanie najdlhšej zhody v rámci vyhľadávacieho okna.
 | ||||||
|         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 && | ||||||
|                    pos + match_length < size && |                    pos + match_length < size && | ||||||
|                    data[i + match_length] == data[pos + match_length]) { |                    data[i + match_length] == data[pos + match_length]) { | ||||||
|                 match_length++; |                 match_length++; // Počítanie dĺžky zhody.
 | ||||||
|             } |             } | ||||||
|             if (match_length > best_match_length) { |             if (match_length > best_match_length) { // Aktualizácia najlepšieho zhody.
 | ||||||
|                 best_match_length = match_length; |                 best_match_length = match_length; | ||||||
|                 best_match_offset = pos - i; |                 best_match_offset = pos - i; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         unsigned char offset_high = (best_match_offset >> 8) & 0xFF; |         // Zápis zhody a nasledujúceho symbolu do súboru.
 | ||||||
|         unsigned char offset_low = best_match_offset & 0xFF; |         unsigned char offset_high = (best_match_offset >> 8) & 0xFF; // Vyšších 8 bitov posunu.
 | ||||||
|         unsigned char length = best_match_length; |         unsigned char offset_low = best_match_offset & 0xFF; // Nižších 8 bitov posunu.
 | ||||||
|         unsigned char next_symbol = (pos + best_match_length < size) ? data[pos + best_match_length] : 0; |         unsigned char length = best_match_length; // Dĺžka zhody.
 | ||||||
|  |         unsigned char next_symbol = (pos + best_match_length < size) ? data[pos + best_match_length] : 0; // Nasledujúci symbol.
 | ||||||
| 
 | 
 | ||||||
|         fputc(offset_high, output_file); |         fputc(offset_high, output_file); | ||||||
|         fputc(offset_low, output_file); |         fputc(offset_low, output_file); | ||||||
|         fputc(length, output_file); |         fputc(length, output_file); | ||||||
|         fputc(next_symbol, output_file); |         fputc(next_symbol, output_file); | ||||||
| 
 | 
 | ||||||
|         pos += best_match_length + 1; |         pos += best_match_length + 1; // Posun v prehliadacom okne.
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fclose(output_file); |     fclose(output_file); // Uzavretie výstupného súboru.
 | ||||||
|     free(data); |     free(data); // Uvoľnenie načítaných dát.
 | ||||||
| 
 | 
 | ||||||
|     printf("Compression using LZ77 completed successfully.\n"); |     printf("Compression using LZ77 completed successfully.\n"); | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | // Funkcia na dekompresiu súboru komprimovaného LZ77 algoritmom.
 | ||||||
| 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_file = fopen(input_file_name, "rb"); |     FILE* input_file = fopen(input_file_name, "rb"); // Otvorenie vstupného súboru v binárnom režime.
 | ||||||
|     if (!input_file) { |     if (!input_file) { | ||||||
|         perror("Error opening input file"); |         perror("Error opening input file"); | ||||||
|         return -1; |         return -1; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     FILE* output_file = fopen(output_file_name, "wb"); |     FILE* output_file = fopen(output_file_name, "wb"); // Otvorenie výstupného súboru v binárnom režime.
 | ||||||
|     if (!output_file) { |     if (!output_file) { | ||||||
|         perror("Error opening output file"); |         perror("Error opening output file"); | ||||||
|         fclose(input_file); |         fclose(input_file); | ||||||
|         return -1; |         return -1; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     unsigned char* output_buffer = (unsigned char*)malloc(10 * 1024 * 1024); // Pre alokáciu 10 MB
 |     unsigned char* output_buffer = (unsigned char*)malloc(10 * 1024 * 1024); // Alokácia bufferu na dekomprimované dáta (max. 10 MB).
 | ||||||
|     if (!output_buffer) { |     if (!output_buffer) { | ||||||
|         perror("Memory allocation error"); |         perror("Memory allocation error"); | ||||||
|         fclose(input_file); |         fclose(input_file); | ||||||
| @ -336,31 +347,32 @@ int decompress_2(const char* input_file_name, const char* output_file_name) { | |||||||
| 
 | 
 | ||||||
|     size_t pos = 0; |     size_t pos = 0; | ||||||
|     while (1) { |     while (1) { | ||||||
|  |         // Čítanie posunu, dĺžky a nasledujúceho symbolu zo vstupného súboru.
 | ||||||
|         int offset_high = fgetc(input_file); |         int offset_high = fgetc(input_file); | ||||||
|         int offset_low = fgetc(input_file); |         int offset_low = fgetc(input_file); | ||||||
|         int length = fgetc(input_file); |         int length = fgetc(input_file); | ||||||
|         int next_symbol = fgetc(input_file); |         int next_symbol = fgetc(input_file); | ||||||
| 
 | 
 | ||||||
|         if (offset_high == EOF || offset_low == EOF || length == EOF || next_symbol == EOF) break; |         if (offset_high == EOF || offset_low == EOF || length == EOF || next_symbol == EOF) break; // Koniec súboru.
 | ||||||
| 
 |  | ||||||
|         size_t offset = (offset_high << 8) | offset_low; |  | ||||||
| 
 | 
 | ||||||
|  |         size_t offset = (offset_high << 8) | offset_low; // Zloženie posunu z vyšších a nižších bitov.
 | ||||||
| 
 | 
 | ||||||
|  |         // Obnovenie zhody z výstupného bufferu.
 | ||||||
|         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++; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| 
 |         // Zapísanie nasledujúceho symbolu do bufferu.
 | ||||||
|         output_buffer[pos++] = next_symbol; |         output_buffer[pos++] = next_symbol; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fwrite(output_buffer, 1, pos, output_file); |     fwrite(output_buffer, 1, pos, output_file); // Zápis dekomprimovaných dát do súboru.
 | ||||||
| 
 | 
 | ||||||
|     free(output_buffer); |     free(output_buffer); // Uvoľnenie alokovaného bufferu.
 | ||||||
|     fclose(input_file); |     fclose(input_file); // Uzavretie vstupného súboru.
 | ||||||
|     fclose(output_file); |     fclose(output_file); // Uzavretie výstupného súboru.
 | ||||||
| 
 | 
 | ||||||
|     printf("Decompression using LZ77 completed successfully.\n"); |     printf("Decompression using LZ77 completed successfully.\n"); | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
							
								
								
									
										0
									
								
								sk2/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								sk2/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								sk2/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								sk2/README.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								sk2/calculator.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								sk2/calculator.c
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								sk2/calculator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								sk2/calculator.h
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								sk2/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								sk2/main.c
									
									
									
									
									
										Normal file
									
								
							
		Loading…
	
		Reference in New Issue
	
	Block a user