-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdecompress.c
155 lines (130 loc) · 4.89 KB
/
decompress.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include "decompress.h"
// Função para escrever o arquivo descomprimido
void write_decompress(Tree *bt, FILE *entrada, FILE *saida, int lixo)
{
// Define um ponteiro auxiliar para a árvore de Huffman
Tree *aux = bt;
// Define variáveis para armazenar os caracteres lidos do arquivo e um auxiliar
BYTE character, aux1;
int i;
// Lê o primeiro caractere do arquivo de entrada
fscanf(entrada, "%c", &character);
aux1 = character;
// Lê cada caractere do arquivo de entrada até o final
while (fscanf(entrada, "%c", &character) != EOF)
{
// Loop para cada bit do caractere
for (i = 7; i >= 0; i--)
{
// Se o nó atual é uma folha (não tem filhos)
if (aux->left == NULL && aux->right == NULL)
{
// Escreve o caractere do nó no arquivo de saída
fprintf(saida, "%c", aux->character);
// Reinicia o ponteiro auxiliar para o início da árvore
aux = bt;
}
// Se o bit na posição atual é 1, move o ponteiro auxiliar para a direita
if (aux1 & 1 << i)
aux = aux->right;
// Se o bit na posição atual é 0, move o ponteiro auxiliar para a esquerda
else
aux = aux->left;
}
aux1 = character;
}
// Loop para os bits restantes no último byte
for (i = 7; lixo <= 8; lixo++, i--)
{
// Se o nó atual é uma folha (não tem filhos)
if (aux->left == NULL && aux->right == NULL)
{
fprintf(saida, "%c", aux->character);
aux = bt;
}
// Se o bit na posição atual é 1, move o ponteiro auxiliar para a direita
if (aux1 & 1 << i)
aux = aux->right;
// Se o bit na posição atual é 0, move o ponteiro auxiliar para a esquerda
else
aux = aux->left;
}
return;
}
// Função para verificar se o nome do arquivo termina com ".comp"
int verification(char *nome)
{
int condition = 0, i, j, size = strlen(nome);
char *comp;
comp = ".comp";
for (i = size - 1, j = 4; i > size - 6; i--, j--)
if (comp[j] != nome[i])
condition = 1;
if (condition)
{
printf("Nao se trata de um arquivo compactado.\nArquivos compactados devem ter a extensao: .comp\n");
system("pause");
}
return condition;
}
// Função para descomprimir o arquivo
void decompress(char *nome_entrada)
{
char nome_saida[200];
FILE *arquivo_entrada;
FILE *arquivo_saida;
BYTE character;
int lixo, size_tree = 0, i;
Tree *bt = NULL;
// Loop infinito para tentar abrir o arquivo de entrada
while (1)
{
system("cls");
// Tenta abrir o arquivo de entrada no modo de leitura binária
arquivo_entrada = fopen(nome_entrada, "rb");
if (arquivo_entrada == NULL)
{
printf("O nome do arquivo ou caminho esta incorreto!\n Tente novamente...");
system("pause");
continue;
}
// Se a verificação do nome do arquivo passar (ou seja, o arquivo tem a extensão ".comp")
if (verification(nome_entrada))
continue;
break;
}
// Copia o nome do arquivo de entrada para o nome do arquivo de saída, excluindo a extensão ".comp"
strncpy(nome_saida, nome_entrada, strlen(nome_entrada) - 5);
nome_saida[strlen(nome_entrada) - 5] = '\0';
// Lê o primeiro caractere do arquivo de entrada
fscanf(arquivo_entrada, "%c", &character);
// Extrai os 3 bits mais significativos, que representam o tamanho do lixo
lixo = character >> 5;
// Extrai os 5 bits menos significativos do primeiro caractere, que representam a parte alta do tamanho da árvore
size_tree = character & 0b00011111;
// Desloca os bits para a esquerda para fazer espaço para a parte baixa do tamanho da árvore
size_tree = size_tree << 8;
// Lê o próximo caractere do arquivo de entrada
fscanf(arquivo_entrada, "%c", &character);
// Combina a parte baixa do tamanho da árvore com a parte alta
size_tree = size_tree | character;
system("cls");
// Se o tamanho da árvore é 2, chama a função de exceção para reconstruir a árvore de Huffman
if (size_tree == 2)
bt = (Tree *)func_exception(arquivo_entrada);
// Se o tamanho da árvore não é 2, chama a função normal para reconstruir a árvore de Huffman
else
bt = rebuild_huffman_tree(arquivo_entrada);
arquivo_saida = fopen(nome_saida, "wb");
if (arquivo_saida == NULL)
{
printf("Erro ao abrir o arquivo de saída!\n");
return;
}
// Chama a função para escrever o arquivo descomprimido
write_decompress(bt, arquivo_entrada, arquivo_saida, lixo);
printf(" Concluido com exito\n");
fclose(arquivo_saida);
fclose(arquivo_entrada);
return;
}