skuska2
This commit is contained in:
		
							parent
							
								
									8682cad5c2
								
							
						
					
					
						commit
						0f9977f603
					
				
							
								
								
									
										234
									
								
								sk1/compressor.c
									
									
									
									
									
								
							
							
						
						
									
										234
									
								
								sk1/compressor.c
									
									
									
									
									
								
							| @ -1,66 +1,71 @@ | ||||
| #include "compressor.h" | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.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>      // Knižnica pre prácu so vstupom a výstupom. | ||||
| #include <stdlib.h>     // Knižnica pre alokáciu pamäte a ďalšie základné funkcie. | ||||
| #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) { | ||||
|     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) { | ||||
|         perror("Error opening file"); | ||||
|         perror("Error opening file"); // Chybové hlásenie, ak sa súbor nedá otvoriť.
 | ||||
|         return NULL; | ||||
|     } | ||||
| 
 | ||||
|     fseek(file, 0, SEEK_END); | ||||
|     *size = ftell(file); | ||||
|     rewind(file); | ||||
|     fseek(file, 0, SEEK_END);  // Posun ukazovateľa na koniec súboru.
 | ||||
|     *size = ftell(file);       // Zistenie veľkosti súboru.
 | ||||
|     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) { | ||||
|         perror("Memory allocation error"); | ||||
|         perror("Memory allocation error"); // Chybové hlásenie, ak sa nepodarí alokovať pamäť.
 | ||||
|         fclose(file); | ||||
|         return NULL; | ||||
|     } | ||||
| 
 | ||||
|     fread(buffer, 1, *size, file); | ||||
|     fread(buffer, 1, *size, file); // Načítanie obsahu súboru do bufferu.
 | ||||
|     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) { | ||||
|     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) { | ||||
|         perror("Error opening file"); | ||||
|         return -1; | ||||
|     } | ||||
| 
 | ||||
|     fwrite(buffer, 1, size, file); | ||||
|     fwrite(buffer, 1, size, file); // Zápis dát do súboru.
 | ||||
|     fclose(file); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| // Funkcia na vytvorenie Huffmanovho stromu z daných dát.
 | ||||
| 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++) { | ||||
|         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; | ||||
| 
 | ||||
|     // Vytvorenie listových uzlov pre znaky s nenulovou frekvenciou.
 | ||||
|     for (int i = 0; i < 256; i++) { | ||||
|         if (frequencies[i] > 0) { | ||||
|             HuffmanNode* node = (HuffmanNode*)malloc(sizeof(HuffmanNode)); | ||||
|             node->symbol = (unsigned char)i; | ||||
|             node->frequency = frequencies[i]; | ||||
|             node->symbol = (unsigned char)i; // Znak reprezentovaný uzlom.
 | ||||
|             node->frequency = frequencies[i]; // Frekvencia znaku.
 | ||||
|             node->left = 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) { | ||||
| 
 | ||||
|         // Vyhľadanie dvoch uzlov s najnižšou frekvenciou.
 | ||||
|         int min1 = 0, min2 = 1; | ||||
|         if (nodes[min2]->frequency < nodes[min1]->frequency) { | ||||
|             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)); | ||||
|         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->left = nodes[min1]; | ||||
|         new_node->right = nodes[min2]; | ||||
| 
 | ||||
|         // Aktualizácia zoznamu uzlov.
 | ||||
|         nodes[min1] = new_node; | ||||
|         nodes[min2] = nodes[node_count - 1]; | ||||
|         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) { | ||||
|     if (!root->left && !root->right) { | ||||
|         buffer[depth] = '\0'; | ||||
|         codes[root->symbol] = strdup(buffer); | ||||
|     if (!root->left && !root->right) { // Ak uzol nemá potomkov, je to listový uzol.
 | ||||
|         buffer[depth] = '\0'; // Ukončenie reťazca.
 | ||||
|         codes[root->symbol] = strdup(buffer); // Uloženie kódu pre znak.
 | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if (root->left) { | ||||
|         buffer[depth] = '0'; | ||||
|         buffer[depth] = '0'; // Pridanie '0' pre cestu doľava.
 | ||||
|         generate_huffman_codes(root->left, codes, buffer, depth + 1); | ||||
|     } | ||||
| 
 | ||||
|     if (root->right) { | ||||
|         buffer[depth] = '1'; | ||||
|         buffer[depth] = '1'; // Pridanie '1' pre cestu doprava.
 | ||||
|         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) { | ||||
|     if (!root) return; | ||||
|     free_huffman_tree(root->left); | ||||
|     free_huffman_tree(root->right); | ||||
|     free(root); | ||||
|     if (!root) return; // Ak je strom prázdny, nič nerobí.
 | ||||
|     free_huffman_tree(root->left);  // Rekurzívne uvoľnenie ľavého podstromu.
 | ||||
|     free_huffman_tree(root->right); // Rekurzívne uvoľnenie pravého podstromu.
 | ||||
|     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) { | ||||
|     for (int i = 0; bits[i] != '\0'; i++) { | ||||
|         if (bits[i] == '1') { | ||||
|     for (int i = 0; bits[i] != '\0'; i++) { // Prechádza všetky bity v reťazci.
 | ||||
|         if (bits[i] == '1') { // Ak je bit '1', nastaví príslušný bit v bufferi.
 | ||||
|             buffer[*bit_pos / 8] |= (1 << (7 - (*bit_pos % 8))); | ||||
|         } | ||||
|         (*bit_pos)++; | ||||
|         if (*bit_pos % 8 == 0) { | ||||
|         (*bit_pos)++; // Posunie sa na ďalšiu bitovú pozíciu.
 | ||||
| 
 | ||||
|         if (*bit_pos % 8 == 0) { // Ak je buffer plný (8 bitov), zapíše sa do súboru.
 | ||||
|             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) { | ||||
|     if (*bit_pos % 8 == 0) { | ||||
|         if (fread(buffer, 1, 1, file) != 1) return -1;  | ||||
|     if (*bit_pos % 8 == 0) { // Ak sa číta nový bajt, načíta ho do bufferu.
 | ||||
|         if (fread(buffer, 1, 1, file) != 1) return -1; // Ak sa nedá čítať, vráti chybu.
 | ||||
|     } | ||||
|     int bit = (*buffer >> (7 - (*bit_pos % 8))) & 1; | ||||
|     (*bit_pos)++; | ||||
|     int bit = (*buffer >> (7 - (*bit_pos % 8))) & 1; // Získa hodnotu aktuálneho bitu.
 | ||||
|     (*bit_pos)++; // Posunie sa na ďalšiu bitovú pozíciu.
 | ||||
|     return bit; | ||||
| } | ||||
| 
 | ||||
| // Funkcia na deserializáciu Huffmanovho stromu zo súboru.
 | ||||
| HuffmanNode* deserialize_tree(FILE* file) { | ||||
|     int marker = fgetc(file); | ||||
|     if (marker == EOF) return NULL; | ||||
| 
 | ||||
|     if (marker == '1') { | ||||
|     int marker = fgetc(file); // Prečíta znak z binárneho súboru.
 | ||||
|     if (marker == EOF) return NULL; // Ak je súbor na konci, vráti NULL.
 | ||||
| 
 | ||||
|     if (marker == '1') { // Ak je marker '1', ide o listový uzol.
 | ||||
|         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; | ||||
|         return node; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     // Ak je marker '0', ide o vnútorný uzol. Rekurzívne načíta podstromy.
 | ||||
|     HuffmanNode* node = (HuffmanNode*)malloc(sizeof(HuffmanNode)); | ||||
|     node->left = deserialize_tree(file); | ||||
|     node->right = deserialize_tree(file); | ||||
|     return node; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // Funkcia na kompresiu súboru pomocou Huffmanovho kódovania.
 | ||||
| int compress_1(const char* input_file_name, const char* output_file_name) { | ||||
|     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; | ||||
| 
 | ||||
|     HuffmanNode* root = build_huffman_tree(data, size); | ||||
|     HuffmanNode* root = build_huffman_tree(data, size); // Vytvorenie Huffmanovho stromu.
 | ||||
|     if (!root) { | ||||
|         free(data); | ||||
|         return -1; | ||||
|     } | ||||
| 
 | ||||
|     char* codes[256] = {0}; | ||||
|     char* codes[256] = {0}; // Pole na uloženie kódov pre každý znak.
 | ||||
|     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"); | ||||
|     FILE* output_file = fopen(output_file_name, "wb"); // Otvorenie výstupného súboru.
 | ||||
|     if (!output_file) { | ||||
|         perror("Error opening output file"); | ||||
|         free(data); | ||||
| @ -181,152 +193,151 @@ int compress_1(const char* input_file_name, const char* output_file_name) { | ||||
|         return -1; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     unsigned char bit_buffer[1] = {0}; | ||||
|     unsigned char bit_buffer[1] = {0}; // Dočasný buffer na bity.
 | ||||
|     int bit_pos = 0; | ||||
| 
 | ||||
|     for (size_t i = 0; i < size; i++) { | ||||
|         write_bits(output_file, codes[data[i]], bit_buffer, &bit_pos); | ||||
|     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); // 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); | ||||
|     } | ||||
| 
 | ||||
|     fclose(output_file); | ||||
|     fclose(output_file); // Uzavretie výstupného súboru.
 | ||||
| 
 | ||||
|     printf("Compressing using Huffman coding...\n"); | ||||
| 
 | ||||
| 
 | ||||
|     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(data); | ||||
|     free_huffman_tree(root); // Uvoľnenie pamäte pre Huffmanov strom.
 | ||||
|     free(data); // Uvoľnenie dátového bufferu.
 | ||||
| 
 | ||||
|     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) { | ||||
|     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) { | ||||
|         perror("Error opening input file"); | ||||
|         perror("Error opening input file"); // Chybové hlásenie, ak sa súbor nedá otvoriť.
 | ||||
|         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) { | ||||
|         perror("Error opening output file"); | ||||
|         fclose(input_file); | ||||
|         return -1; | ||||
|     } | ||||
| 
 | ||||
|      | ||||
|     HuffmanNode* root = deserialize_tree(input_file); | ||||
|     HuffmanNode* root = deserialize_tree(input_file); // Načítanie Huffmanovho stromu zo súboru.
 | ||||
|     if (!root) { | ||||
|         fclose(input_file); | ||||
|         fclose(output_file); | ||||
|         return -1; | ||||
|     } | ||||
| 
 | ||||
|      | ||||
|     unsigned char bit_buffer[1]; | ||||
|     unsigned char bit_buffer[1]; // Buffer na čítanie bitov.
 | ||||
|     int bit_pos = 0; | ||||
|     HuffmanNode* current = root; | ||||
|     HuffmanNode* current = root; // Počiatočný uzol stromu.
 | ||||
| 
 | ||||
|     while (1) { | ||||
|         int bit = read_bit(input_file, bit_buffer, &bit_pos); | ||||
|         if (bit == -1) break; | ||||
|         int bit = read_bit(input_file, bit_buffer, &bit_pos); // Čítanie bitu zo súboru.
 | ||||
|         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) { | ||||
|             fputc(current->symbol, output_file); | ||||
|             current = root; | ||||
|         if (!current->left && !current->right) { // Ak je uzol listový, znamená to dekódovaný znak.
 | ||||
|             fputc(current->symbol, output_file); // Zapíše sa znak do výstupného súboru.
 | ||||
|             current = root; // Návrat na koreň stromu pre ďalší znak.
 | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fclose(input_file); | ||||
|     fclose(output_file); | ||||
|     free_huffman_tree(root); | ||||
|     fclose(input_file); // Uzavretie vstupného súboru.
 | ||||
|     fclose(output_file); // Uzavretie výstupného súboru.
 | ||||
|     free_huffman_tree(root); // Uvoľnenie pamäte Huffmanovho stromu.
 | ||||
| 
 | ||||
|     printf("Decompressing using Huffman coding...\n"); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // Funkcia na kompresiu súboru pomocou LZ77 algoritmu.
 | ||||
| int compress_2(const char* input_file_name, const char* output_file_name) { | ||||
|     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; | ||||
| 
 | ||||
|     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) { | ||||
|         perror("Error opening output file"); | ||||
|         free(data); | ||||
|         return -1; | ||||
|     } | ||||
| 
 | ||||
|     size_t search_buffer_size = 1024;  | ||||
|     size_t lookahead_buffer_size = 16;  | ||||
|     size_t search_buffer_size = 1024; // Veľkosť vyhľadávacieho okna.
 | ||||
|     size_t lookahead_buffer_size = 16; // Veľkosť prehliadacieho okna.
 | ||||
| 
 | ||||
|     size_t pos = 0; | ||||
|     while (pos < size) { | ||||
|         size_t best_match_offset = 0; | ||||
|         size_t best_match_length = 0; | ||||
|         size_t best_match_offset = 0; // Najlepší posun pre aktuálny segment.
 | ||||
|         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++) { | ||||
|             size_t match_length = 0; | ||||
|             while (match_length < lookahead_buffer_size && | ||||
|                    pos + match_length < size && | ||||
|                    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_offset = pos - i; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         unsigned char offset_high = (best_match_offset >> 8) & 0xFF; | ||||
|         unsigned char offset_low = best_match_offset & 0xFF; | ||||
|         unsigned char length = best_match_length; | ||||
|         unsigned char next_symbol = (pos + best_match_length < size) ? data[pos + best_match_length] : 0; | ||||
|         // Zápis zhody a nasledujúceho symbolu do súboru.
 | ||||
|         unsigned char offset_high = (best_match_offset >> 8) & 0xFF; // Vyšších 8 bitov posunu.
 | ||||
|         unsigned char offset_low = best_match_offset & 0xFF; // Nižších 8 bitov posunu.
 | ||||
|         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_low, output_file); | ||||
|         fputc(length, output_file); | ||||
|         fputc(next_symbol, output_file); | ||||
| 
 | ||||
|         pos += best_match_length + 1; | ||||
|         pos += best_match_length + 1; // Posun v prehliadacom okne.
 | ||||
|     } | ||||
| 
 | ||||
|     fclose(output_file); | ||||
|     free(data); | ||||
|     fclose(output_file); // Uzavretie výstupného súboru.
 | ||||
|     free(data); // Uvoľnenie načítaných dát.
 | ||||
| 
 | ||||
|     printf("Compression using LZ77 completed successfully.\n"); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // Funkcia na dekompresiu súboru komprimovaného LZ77 algoritmom.
 | ||||
| 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) { | ||||
|         perror("Error opening input file"); | ||||
|         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) { | ||||
|         perror("Error opening output file"); | ||||
|         fclose(input_file); | ||||
|         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) { | ||||
|         perror("Memory allocation error"); | ||||
|         fclose(input_file); | ||||
| @ -336,30 +347,31 @@ int decompress_2(const char* input_file_name, const char* output_file_name) { | ||||
| 
 | ||||
|     size_t pos = 0; | ||||
|     while (1) { | ||||
|         // Čítanie posunu, dĺžky a nasledujúceho symbolu zo vstupného súboru.
 | ||||
|         int offset_high = fgetc(input_file); | ||||
|         int offset_low = fgetc(input_file); | ||||
|         int length = fgetc(input_file); | ||||
|         int next_symbol = fgetc(input_file); | ||||
| 
 | ||||
|         if (offset_high == EOF || offset_low == EOF || length == EOF || next_symbol == EOF) break; | ||||
| 
 | ||||
|         size_t offset = (offset_high << 8) | offset_low; | ||||
|         if (offset_high == EOF || offset_low == EOF || length == EOF || next_symbol == EOF) break; // Koniec súboru.
 | ||||
| 
 | ||||
|         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++) { | ||||
|             output_buffer[pos] = output_buffer[pos - offset]; | ||||
|             pos++; | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         // Zapísanie nasledujúceho symbolu do bufferu.
 | ||||
|         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); | ||||
|     fclose(input_file); | ||||
|     fclose(output_file); | ||||
|     free(output_buffer); // Uvoľnenie alokovaného bufferu.
 | ||||
|     fclose(input_file); // Uzavretie vstupného súboru.
 | ||||
|     fclose(output_file); // Uzavretie výstupného súboru.
 | ||||
| 
 | ||||
|     printf("Decompression using LZ77 completed successfully.\n"); | ||||
|     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