-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdecoding.cpp
142 lines (131 loc) · 3.37 KB
/
decoding.cpp
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
/*
Yuvraj Singh
200670570
*/
#include <fstream>
#include <iostream>
#include <string.h>
#include <vector>
using std::string;
struct node {
char ch;
int freq = 0;
node *left = nullptr;
node *right = nullptr;
node(char character) : ch(character) {}
};
class heap {
private:
std::vector<node *> pQueue;
int parent(int i) {
return (i - 1) / 2;
}
int left(int i) {
return (2 * i + 1);
}
int right(int i) {
return (2 * i + 2);
}
void heapify_down(int i) {
int l = left(i);
int r = right(i);
int smallest = i;
if (l < size() && pQueue[l]->freq < pQueue[i]->freq) {
smallest = l;
}
if (r < size() && pQueue[r]->freq < pQueue[smallest]->freq) {
smallest = r;
}
if (smallest != i) {
swap(pQueue[i], pQueue[smallest]);
heapify_down(smallest);
}
}
void heapify_up(int i) {
if (i && pQueue[parent(i)]->freq > pQueue[i]->freq) {
swap(pQueue[i], pQueue[parent(i)]);
heapify_up(parent(i));
}
}
void swap(node *i, node *j) {
node temp = *i;
*i = *j;
*j = temp;
}
public:
heap() {}
node *popRoot() {
node *temp = pQueue.at(0);
pQueue[0] = pQueue.back();
pQueue.pop_back();
heapify_down(0);
return temp;
}
void insert(node *newNode) {
pQueue.push_back(newNode);
heapify_up(pQueue.size() - 1);
}
node *getRoot() {
return pQueue.at(0);
}
int size() {
return pQueue.size();
}
};
void reconstructHuffman(heap &codes) {
string line;
node *child1, *child2, *subTree;
std::ifstream myfile("frequency.txt");
if (myfile.is_open()) {
while (getline(myfile, line)) {
node *ch = new node(line[0]);
ch->freq = stoi(line.substr(2));
codes.insert(ch);
}
myfile.close();
}
// create tree
while (codes.size() > 1) {
child1 = codes.popRoot();
child2 = codes.popRoot();
subTree = new node('^');
subTree->freq = child1->freq + child2->freq;
subTree->left = child1;
subTree->right = child2;
codes.insert(subTree);
}
}
void decode(heap &codes) {
unsigned char mask, ch = 0, temp;
char bit = 0;
int j = 0;
node *tempChar = codes.getRoot();
std::ofstream myFile("decoded.txt");
std::ifstream file("compressed.bin", std::ios::binary);
std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(file), {});
file.close();
while (j != buffer.size()) {
mask = 128;
mask = mask >> bit++; // right shift mask based on current bit position
ch = buffer[j] & mask;
if (ch) // find code by going through tree
tempChar = tempChar->left;
else
tempChar = tempChar->right;
if (tempChar->right == nullptr && tempChar->left == nullptr) { // leaf node (node with character) reached
myFile << tempChar->ch;
tempChar = codes.getRoot(); // reset node
}
if (bit == 8) { // move to next buffer index and reset bit
j++;
bit = 0;
}
}
myFile.close();
}
int main() {
heap codes;
reconstructHuffman(codes);
decode(codes);
std::cout << "Finished" << std::endl;
}