Обновить sk1/compressor.c
This commit is contained in:
		
							parent
							
								
									1a4906801b
								
							
						
					
					
						commit
						ddfe40aa8a
					
				| @ -24,7 +24,6 @@ typedef struct LZ77{ | |||||||
|     char dalsi_znak; |     char dalsi_znak; | ||||||
| } LZ77; | } LZ77; | ||||||
| 
 | 
 | ||||||
| // Функция для создания нового узла
 |  | ||||||
| Node* create_node(int symbol, unsigned int frequency) { | Node* create_node(int symbol, unsigned int frequency) { | ||||||
|     Node* node = (Node*)malloc(sizeof(Node)); |     Node* node = (Node*)malloc(sizeof(Node)); | ||||||
|     node->symbol = symbol; |     node->symbol = symbol; | ||||||
| @ -33,19 +32,16 @@ Node* create_node(int symbol, unsigned int frequency) { | |||||||
|     return node; |     return node; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Функция для построения дерева Хаффмана
 |  | ||||||
| Node* build_huffman_tree(const unsigned int* frequencies) { | Node* build_huffman_tree(const unsigned int* frequencies) { | ||||||
|     Node* nodes[MAX_SYMBOLS]; |     Node* nodes[MAX_SYMBOLS]; | ||||||
|     int node_count = 0; |     int node_count = 0; | ||||||
| 
 | 
 | ||||||
|     // Создаем узлы для всех символов с ненулевой частотой
 |  | ||||||
|     for (int i = 0; i < MAX_SYMBOLS; i++) { |     for (int i = 0; i < MAX_SYMBOLS; i++) { | ||||||
|         if (frequencies[i] > 0) { |         if (frequencies[i] > 0) { | ||||||
|             nodes[node_count++] = create_node(i, frequencies[i]); |             nodes[node_count++] = create_node(i, frequencies[i]); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Объединяем узлы в дерево
 |  | ||||||
|     while (node_count > 1) { |     while (node_count > 1) { | ||||||
|         // Сортируем узлы по частоте
 |         // Сортируем узлы по частоте
 | ||||||
|         for (int i = 0; i < node_count - 1; i++) { |         for (int i = 0; i < node_count - 1; i++) { | ||||||
| @ -56,7 +52,6 @@ Node* build_huffman_tree(const unsigned int* frequencies) { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Объединяем два узла с наименьшей частотой
 |  | ||||||
|         Node* left = nodes[0]; |         Node* left = nodes[0]; | ||||||
|         Node* right = nodes[1]; |         Node* right = nodes[1]; | ||||||
|         Node* parent = create_node(-1, left->frequency + right->frequency); |         Node* parent = create_node(-1, left->frequency + right->frequency); | ||||||
| @ -71,24 +66,22 @@ Node* build_huffman_tree(const unsigned int* frequencies) { | |||||||
|     return nodes[0]; |     return nodes[0]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Рекурсивная функция для генерации кодов Хаффмана
 |  | ||||||
| void generate_huffman_codes(Node* root, char* code, int depth, char codes[MAX_SYMBOLS][MAX_SYMBOLS]) { | void generate_huffman_codes(Node* root, char* code, int depth, char codes[MAX_SYMBOLS][MAX_SYMBOLS]) { | ||||||
|     if (!root->left && !root->right) { |     if (!root->left && !root->right) { | ||||||
|         code[depth] = '\0'; // Завершаем код символа
 |         code[depth] = '\0';  | ||||||
|         strcpy(codes[root->symbol], code); |         strcpy(codes[root->symbol], code); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     if (root->left) { |     if (root->left) { | ||||||
|         code[depth] = '0'; // Добавляем бит '0' для левого поддерева
 |         code[depth] = '0';  | ||||||
|         generate_huffman_codes(root->left, code, depth + 1, codes); |         generate_huffman_codes(root->left, code, depth + 1, codes); | ||||||
|     } |     } | ||||||
|     if (root->right) { |     if (root->right) { | ||||||
|         code[depth] = '1'; // Добавляем бит '1' для правого поддерева
 |         code[depth] = '1';  | ||||||
|         generate_huffman_codes(root->right, code, depth + 1, codes); |         generate_huffman_codes(root->right, code, depth + 1, codes); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Функция для освобождения памяти, выделенной под дерево Хаффмана
 |  | ||||||
| void free_huffman_tree(Node* root) { | void free_huffman_tree(Node* root) { | ||||||
|     if (!root) return; |     if (!root) return; | ||||||
|     free_huffman_tree(root->left); |     free_huffman_tree(root->left); | ||||||
| @ -96,7 +89,6 @@ void free_huffman_tree(Node* root) { | |||||||
|     free(root); |     free(root); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Функция сжатия данных с использованием алгоритма Хаффмана
 |  | ||||||
| int compress_1(const char* input_file, const char* output_file) { | int compress_1(const char* input_file, const char* output_file) { | ||||||
|     FILE* input = fopen(input_file, "rb"); |     FILE* input = fopen(input_file, "rb"); | ||||||
|     FILE* output = fopen(output_file, "wb"); |     FILE* output = fopen(output_file, "wb"); | ||||||
| @ -122,10 +114,9 @@ int compress_1(const char* input_file, const char* output_file) { | |||||||
|     char code[MAX_SYMBOLS] = {0}; |     char code[MAX_SYMBOLS] = {0}; | ||||||
|     generate_huffman_codes(root, code, 0, codes); |     generate_huffman_codes(root, code, 0, codes); | ||||||
| 
 | 
 | ||||||
|     // Записываем частоты в выходной файл
 | 
 | ||||||
|     fwrite(frequencies, sizeof(frequencies[0]), MAX_SYMBOLS, output); |     fwrite(frequencies, sizeof(frequencies[0]), MAX_SYMBOLS, output); | ||||||
| 
 | 
 | ||||||
|     // Сжимаем данные
 |  | ||||||
|     rewind(input); |     rewind(input); | ||||||
|     unsigned char current_byte = 0; |     unsigned char current_byte = 0; | ||||||
|     int bit_count = 0; |     int bit_count = 0; | ||||||
| @ -145,7 +136,6 @@ int compress_1(const char* input_file, const char* output_file) { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Записываем маркер EOF
 |  | ||||||
|     char* eof_code = codes[256]; |     char* eof_code = codes[256]; | ||||||
|     for (size_t j = 0; eof_code[j] != '\0'; j++) { |     for (size_t j = 0; eof_code[j] != '\0'; j++) { | ||||||
|         current_byte = (current_byte << 1) | (eof_code[j] - '0'); |         current_byte = (current_byte << 1) | (eof_code[j] - '0'); | ||||||
| @ -167,7 +157,6 @@ int compress_1(const char* input_file, const char* output_file) { | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Функция декомпрессии данных с использованием алгоритма Хаффмана
 |  | ||||||
| int decompress_1(const char* input_file, const char* output_file) { | int decompress_1(const char* input_file, const char* output_file) { | ||||||
|     FILE* input = fopen(input_file, "rb"); |     FILE* input = fopen(input_file, "rb"); | ||||||
|     FILE* output = fopen(output_file, "wb"); |     FILE* output = fopen(output_file, "wb"); | ||||||
| @ -182,7 +171,7 @@ int decompress_1(const char* input_file, const char* output_file) { | |||||||
|     unsigned char byte; |     unsigned char byte; | ||||||
|     int bit; |     int bit; | ||||||
| 
 | 
 | ||||||
|     // Читаем и декодируем символы
 | 
 | ||||||
|     while (fread(&byte, 1, 1, input) == 1) { |     while (fread(&byte, 1, 1, input) == 1) { | ||||||
|         for (bit = 7; bit >= 0; bit--) { |         for (bit = 7; bit >= 0; bit--) { | ||||||
|             current = (byte & (1 << bit)) ? current->right : current->left; |             current = (byte & (1 << bit)) ? current->right : current->left; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user