-
Notifications
You must be signed in to change notification settings - Fork 0
/
uncompress.cpp
113 lines (74 loc) · 2.96 KB
/
uncompress.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
#include <iostream>
#include <string>
#include "Helper.hpp"
#include "HCTree.hpp"
#define EXIT_FAILURE 1
#define EXIT_SUCCESS 0
using namespace std;
/*
Correct command line argument format:
./uncompress <compressed_file> <uncompressed_file>
Note, path needs to be specified:
./uncompress example_files/dna.txt example_files/empty.txt
- argv[0] element is the program name
- argv[1] element is <compressed_file> name, i.e. input file name
- argv[2] element is <uncompressed_file> name, i.e. output file name
argc should equal 3
The outputted uncompressed_file should be the same as the original_file
compressed by ./compress
*/
int main(int argc, char* argv[]) {
/*
* Parse command line arguments and throw error message if user runs program incorrectly
*/
// Check for correct number of input arguments
if (argc != 3) {
cerr << "Wrong number of arguments. Correct format is:\n./uncompress <compressed_file> <uncompressed_file>" << endl;
return EXIT_FAILURE;
}
// check if input file can be opened
ifstream argument_file(argv[1], ios::in);
if (!argument_file.is_open()) {
cerr << "Could not open file: " << argv[1] << "\nFile name or path may be incorrect." << endl;
return EXIT_FAILURE;
}
// open output file
FancyOutputStream o_stream(argv[2]);
FancyInputStream i_stream(argv[1]);
i_stream.reset();
//cout << "Input file size: " << i_stream.filesize() << endl;
// empty file case
if (i_stream.filesize() == 0) {
return EXIT_SUCCESS;
}
vector<int> freq_list(256, 0); // value at index 0 will be the number of times ASCII symbol 0 appears in file
int symbol_count = 0; // total number of symbols encoded in the file
/*
* NAIVE APPROACH:
* Read header (1024 bytes) into freq_list
*/
for (int i = 0; i < 256; i++) {
freq_list[i] = i_stream.read_int();
if (freq_list[i] != 0) {
symbol_count += freq_list[i];
// cout << "(" << (unsigned char)i << "," << freq_list[i] << ")" << endl; // check freq_list is correct
}
}
// build tree
HCTree hc_tree;
hc_tree.build(freq_list);
// hc_tree.print_tree();
// cout << "Symbol count: " << symbol_count << endl;
// Using Huffman tree, decode the bits from input file into the appropriate sequence of bytes (char symbols), writing them to the output file
// Remember: one byte is not the encoding for one symbol. The encoding for one symbol changes depending on path to leaf so don't read_byte in loop condition
// Call decode the same number of times as the number of symbols in the file
for (int i = 0; i < symbol_count; i++) {
/*
THIS PART MAY BE WRONG
*/
unsigned char symbol = hc_tree.decode(i_stream);
o_stream.write_byte(symbol);
}
// Close input and output files; Handled by Destructors of FancyInputStream and FancyOutputStream
return EXIT_SUCCESS;
}