Skip to content

Feature/compress #2

Merged
merged 3 commits into from
May 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#Ignoring text Files
*.txt

#Ignoring all .o file
*.o
1 change: 1 addition & 0 deletions Compress.H
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public:

void generateTree();
void compressFile(string outFile);
void printPreorder();

};

Expand Down
116 changes: 54 additions & 62 deletions Compress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#include <iostream>
#include <vector>
#include <map>
#include <stdlib.h>

using namespace std;

Expand All @@ -13,19 +12,16 @@ map<char,int> Compress::countLetters(){
std::string line;
map<char,int> freq = map<char,int>();

if (inpFile.is_open()){
//This part will count the number of occurences
while(getline(inpFile,line)){
for (char c : line){
freq[c]++;
}
}
return freq;
}
else{
throw(std::string("[Error] Could not open file " + _fname + " for countLetters() \n"));
}
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(){
Expand Down Expand Up @@ -56,69 +52,65 @@ void Compress::generateTree(){
}

template <class Ptr>
string preOrder(Ptr curr){
string preOrder(Ptr curr, string & letters){
if (curr->isLeaf()){
return "1" + string(1,curr->letter);
letters += string(1,curr->letter);
return "1";
}
return preOrder(curr->left) + "0" + preOrder(curr->right);
return preOrder(curr->left,letters) + "0" + preOrder(curr->right,letters);
}

//NEED NUMBER OF BITS FOR BODY
string Compress::generateBody(){
ifstream inpFile(_fname);
if(inpFile.is_open()){
if (_bitMap.size()){
string line; // Reads input file
string compressed = ""; // Will hold compressed body
string uncompressed = ""; // Will hold binary string representation of compression
while(getline(inpFile,line)){
for (char c : line){
uncompressed += _bitMap[c];
}
}

_counter = uncompressed.size();

//Start to divide the binary string into char
int index = 0;
char comp;
for (char c : uncompressed){
if (!index){
comp = 0x0;
}

comp = comp | atoi(&c);

if (index == 7){
compressed += comp;
}
else{
comp = comp << 1; // Shift over one bit
}
index = (index + 1) % 8;
}

if(index){ // If body is not a multiple of 8, then the last few bits need to be copied into compressed
compressed += comp;
}

return compressed;
}
else{
throw("[Error in generateBody()] _bitMap is empty");
}
}
else{
throw("[Error] Could not open file " + _fname + " for generateBody()");

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)){
uncompressed += _bitMap[c];
}
inpFile.close();
_counter = uncompressed.size();
// cout << "Uncompressed string: " << uncompressed << endl;
return convertToBits(uncompressed);
}

void Compress::compressFile(string outFile){
ofstream outF(outFile);
if (!outF.is_open()) throw("[Error] Error accessing file " + outFile + " in compressFile\n");
string body = generateBody();
cout << "Size of Body compressed : " << body.length() << endl;
string header = generateHeader();
cout << header << endl << body << endl;
outF << header + body;
}

string Compress::generateHeader(){
return to_string(_counter) + " " + preOrder(_tree);;
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;
}

void Compress::printPreorder(){
string letts = "";
cout << preOrder(_tree,letts) << endl;
}


int main(int argc, char *argv[]){
using namespace std;
try{
shared_ptr<Compress> conv = make_shared<Compress>(Compress(argv[1]));
conv->generateTree();
conv->generateBitMap();
conv->printPreorder();
conv->compressFile("random");
}
catch(const string &e){cout << e;}
return 0;
}
5 changes: 5 additions & 0 deletions Huffman.H
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <map>
#include <memory>
#include <string>
#include <stdlib.h>

using namespace std;
struct Node;
Expand Down Expand Up @@ -40,4 +41,8 @@ struct Node{
bool isLeaf(){return (!left && !right);}
};

string convertToBits(string uncompressed);//Converts the string format bits into char

string convertToString(string compressed);//Converts the bit form into string form

#endif
41 changes: 41 additions & 0 deletions Huffman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,44 @@ void Huffman::generateBitMapHelper(std::shared_ptr<Node> curr, std::string bin){
void Huffman::generateBitMap(){ //Wrapper class to recursively call enumerateTreeHelper with DFS
generateBitMapHelper(_tree,"");
}

string convertToBits(string uncompressed){ //Converts the string format bits into char
string compressed = "";
int index = 0;
char comp;
for (char c : uncompressed){
if (!index){
comp = 0x0;
}

comp = comp | atoi(&c);

if (index == 7){
compressed += comp;
}
else{
comp = comp << 1; // Shift over one bit
}
index = (index + 1) % 8;
}

if(index){ // If body is not a multiple of 8, then the last few bits need to be copied into compressed
comp = comp << (7-index);
compressed += comp;
}

return compressed;
}

string convertToString(string compressed){//converts from binary form to string form.
string total = "";
for (char c : compressed){
string tmp = "";
for (int i = 0; i < 8;i++){
tmp = to_string(c & 0x1) + tmp;
c = c >> 1;
}
total += tmp;
}
return total;
}
14 changes: 11 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
EXFILES= compress
FILES= main.o Huffman.o Compress.o
EXFILES= compress decompress
DECOMPR=Huffman.o Decompress.o
COMPR=Huffman.o Compress.o
FLAGS= -std=c++14 -g

compress: $(FILES)
all: compress decompress

fresh: clean all

compress: $(COMPR)
g++ $(FLAGS) $^ -o $@

decompress: $(DECOMPR)
g++ $(FLAGS) $^ -o $@

clean:
-rm -f *.o $(EXFILES)

Expand Down
6 changes: 6 additions & 0 deletions main.cpp
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
#include "Huffman.H"
#include "Compress.H"
#include "Decompress.H"

#include <iostream>


int main(int argc, char *argv[]){
using namespace std;
try{
/*
shared_ptr<Compress> conv = make_shared<Compress>(Compress(argv[1]));
conv->generateTree();
conv->generateBitMap();
conv->compressFile("random");
cout << "String bit for A : " << convertToString("A") << endl;
*/
Decompress tst = Decompress(argv[1]);
tst.parseText();
}
catch(string &e){cout << e;}
return 0;
Expand Down