-
Notifications
You must be signed in to change notification settings - Fork 0
/
compress.cpp
143 lines (123 loc) · 2.82 KB
/
compress.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
142
143
/************************************************************************
*
* Kening Zhang, Gang Yang
* CSE 100, fall 17
* 11/9/2017
* cs100fje cs100fiy
*
* Assignment 3
* Filename: compress.cpp
* Description: to compress small files in plain ASCII. First read the
* content of the file named(infile); then construct a Huffman code for the
* contents of that file; last use the code to construct a compressed
* file named(outfile)
************************************************************************/
#include <queue>
#include <vector>
#include <iostream>
#include <fstream>
#include "HCNode.h"
#include "HCTree.h"
#include "BitInputStream.h"
#include "BitOutputStream.h"
#define freq_size 256
#define arg_val 3
#define N_BYTE 3
using namespace std;
typedef unsigned char byte;
/** Use the Huffman algorithm to build a Huffman coding trie.
* PRECONDITION: freqs is a vector of ints, such that freqs[i] is
* the frequency of occurrence of byte i in the message.
* POSTCONDITION: root points to the root of the trie,
* and leaves[i] points to the leaf node containing byte i.
*/
int main(int argc, char** argv){
// check the number of argument
if (argc != arg_val)
{
cout<< "Please enter infile outfile"<< endl;
return false;
}
// open the file
ifstream in;
in.open(argv[1]);
// check whether can open the file
if ( in.is_open()== false )
{
cout<<"Can Not open input file, please retry."<<endl;
return false;
}
// Read bytes from the file
std::vector<int> freqs(freq_size,0);
byte nextChar;
while (1)
{
nextChar=in.get();
if (in.eof())
break;
// cout<< nextChar<<endl;
freqs[(int)nextChar]++;
}
in.close();
// build the Huffman tree
HCTree tree;
tree.build(freqs);
// open the output file for writing
ofstream out;
out.open(argv[2]);
if ( out.is_open()== false )
{
cout<<"Can Not open output file, please retry."<<endl;
return false;
}
/*
// For Fake compress
for (int i=0; i<freqs.size(); i++)
{
// cout<<freqs[i]<<endl;
out<< freqs[i];
out.put('\n');
}
in.open(argv[1]);
if (!in.eof())
{
while (1)
{
nextChar=in.get();
if (in.eof())
break;
// cout<< nextChar<<endl;
tree.encode(nextChar,out);
}
}
in.close();
out.close();
*/
// create the bitoutput instance object
// True Compress
// use the lop for header
for (int i=0; i< freqs.size(); i++)
{
out.write((char*)&freqs[i], N_BYTE*sizeof(char));
}
in.open(argv[1]);
// Output the code
if (!in.eof())
{
BitOutputStream os(out);
while (1)
{
nextChar= in.get();
if (in.eof())
{
// flush the remaining bits in stream
os.flush();
break;
}
tree.encode(nextChar,os);
}
}
// close files
in.close();
out.close();
}