Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
#include "Compress.H"
#include <fstream>
#include <iostream>
#include <vector>
#include <map>
using namespace std;
map<char,int> Compress::countLetters(){
std::ifstream inpFile (_fname); //Will read the file
std::string line;
map<char,int> freq = map<char,int>();
if (!inpFile.is_open()) throw(std::string("[Error] Could not open file " + _fname + " for countLetters() \n"));
//This part will count the number of occurences
char c;
while(inpFile.get(c)){
freq[c]++;
}
inpFile.close();
return freq;
}
void Compress::generateTree(){
map<char,int> freq = countLetters();
vector<shared_ptr<Node>> lst = vector<shared_ptr<Node>>(freq.size());
//Add the char and its frequency into a vector
auto mapit = freq.begin();
for (auto it = lst.begin(); it != lst.end();it++,mapit++){
*it = std::make_shared<Node>(Node(mapit->second,mapit->first,NULL,NULL));
}
while(lst.size() > 1){ //Will combine the two smallest Nodes until there is only one node
std::sort(lst.begin(),lst.end(),[](std::shared_ptr<Node> l1, std::shared_ptr<Node> l2)->bool{return l1->value < l2->value;});
if (lst[0]->value < lst[1]->value){
lst[1] = std::make_shared<Node>(Node(lst[0]->value + lst[1]->value,'\0',lst[0],lst[1]));
}
else{
lst[1] = std::make_shared<Node>(Node(lst[0]->value + lst[1]->value,'\0',lst[1],lst[0]));
}
lst.erase(lst.begin());
}
_tree = lst[0];
}
//NEED NUMBER OF BITS FOR BODY
string Compress::generateBody(){
ifstream inpFile(_fname);
if(!inpFile.is_open()) throw("[Error] Could not open file " + _fname + " for generateBody()");
if (!_bitMap.size()) throw("[Error in generateBody()] _bitMap is empty");
string uncompressed = ""; // Will hold binary string representation of compression
char c;
while(inpFile.get(c)){ //Adding the mapped value for each letter into the total string
uncompressed += _bitMap[c];
}
inpFile.close();
_counter = uncompressed.size();
return convertToBits(uncompressed);
}
void Compress::compressFile(string outFile){
generateTree();
generateBitMap();
ofstream outF(outFile);
if (!outF.is_open()) throw("[Error] Error accessing file " + outFile + " in compressFile\n");
string body = generateBody();
string header = generateHeader();
outF << header + body;
outF.close();
cout << "Compressed " + _fname + " and stored in " + outFile << endl;
}
string Compress::generateHeader(){
string headerLetters = "";
string tmp = preOrder(_tree,headerLetters);
string comp = convertToBits(tmp);
//# of bits in preorder / # of bits in body / preorder in bit form / letters in the preorder tree
return to_string(tmp.size()) + "/" + to_string(_counter) + "/" + comp + headerLetters;
}
/*
int main(int argc, char *argv[]){
using namespace std;
try{
shared_ptr<Compress> conv = make_shared<Compress>(Compress(argv[1]));
conv->compressFile("compressed_" + string(argv[1]));
}
catch(const string &e){cout << e;}
return 0;
}
*/