-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexpand.cpp
More file actions
101 lines (80 loc) · 2.62 KB
/
expand.cpp
File metadata and controls
101 lines (80 loc) · 2.62 KB
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
#include <iostream>
#include <bitset>
#include "huffman_encoder.h"
#include "expand.h"
int expand_file(std::string& inputFileName, std::string& outputFileName, bool verbose) {
std::ifstream inputFile(inputFileName);
if (!inputFile.is_open()) {
perror("open");
return 1;
}
// Read the length of the encoded data
uint32_t length;
inputFile.read(reinterpret_cast<char*>(&length), sizeof(length));
// Read the size of the tree
uint32_t treeSize;
inputFile.read(reinterpret_cast<char*>(&treeSize), sizeof(treeSize));
std::string encodedData;
std::bitset<8> bits;
for (uint32_t i = 0; i < length; i += 8) {
bits = inputFile.get();
encodedData += bits.to_string();
}
// Read the leaf indicator
std::string leafIndicator;
for (uint32_t i = 0; i < treeSize; i += 8) {
bits = inputFile.get();
leafIndicator += bits.to_string();
}
// Remove extra padding on binary data
encodedData.erase(encodedData.begin() + length, encodedData.end());
leafIndicator.erase(leafIndicator.begin() + treeSize, leafIndicator.end());
// Read tree contents
std::string treeValues;
char c;
while (inputFile.get(c)) {
treeValues += c;
}
inputFile.close();
node *huffmanRoot = reconstructTree(leafIndicator, treeValues);
if (verbose) {
printHuffmanTree(huffmanRoot);
}
std::string message = "";
size_t index = 0;
while (index < encodedData.length()) {
node *current = huffmanRoot;
while (current->left || current->right) {
if (encodedData[index] == '0') {
current = current->left;
} else {
current = current->right;
}
index++;
}
message += current->letter;
}
std::ofstream outputFile(outputFileName);
if (!outputFile.is_open()) {
perror("open");
return 1;
}
outputFile << message;
outputFile.close();
return 0;
}
// Function to reconstruct Huffman tree
node *reconstructTree(std::string& structure, std::string& values) {
if (structure.back() == '0') {
node *root = new node{0, '\0', nullptr, nullptr};
structure.pop_back();
root->right = reconstructTree(structure, values);
structure.pop_back();
root->left = reconstructTree(structure, values);
return root;
} else {
node *root = new node{0, values.back(), nullptr, nullptr};
values.pop_back();
return root;
}
}