Skip to content

Commit

Permalink
Merge pull request #2 from top13001/feature/Compress
Browse files Browse the repository at this point in the history
Feature/compress
  • Loading branch information
top13001 committed May 17, 2017
2 parents 4d1573e + ea69b85 commit f6bb3c4
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 65 deletions.
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

0 comments on commit f6bb3c4

Please sign in to comment.