Example #1
0
/** Write to the given BitOutputStream
 *  the sequence of bits coding the given symbol.
 *  PRECONDITION: build() has been called, to create the coding
 *  tree, and initialize root pointer and leaves vector.
 */
void HCTree::encode(byte symbol, BitOutputStream& out) const{

	HCNode* temp = leaves[(int)symbol];
	string ans;
	//read the encoded symbol in string
	while(temp->p != 0){

		if(temp->p->c0 == temp){
			ans = '0' + ans;
		}
		else if(temp->p->c1 == temp){
			ans = '1' + ans;
		}
		temp = temp->p;
	}



	for(int i = 0; i < ans.size(); ++i){
		if(ans[i] == '0'){
			out.writeBit(0);
		}
		else{
			out.writeBit(1);
		}
	}
	


}
Example #2
0
void HCTree::encode(byte symbol, BitOutputStream& out) const{
  HCNode* leaf = leaves[symbol];
  list<int> mylist;
  // Store the bit path of symbol from leaf to root
  while(leaf != this->root) {
    if(leaf->isChild0) {
      mylist.push_back(0);
    }
    else {
      mylist.push_back(1);
    }
    leaf = leaf->parent;
  }
  // Reverse the bit path so it now goes from root to leaf
  mylist.reverse();
  // Go through list and write bits into bitoutputstream
  int i;
  while(mylist.size() != 0) {
    i = mylist.front();
    if(i==0) {
      out.writeBit(0);
    }
    else if(i==1) {
      out.writeBit(1);
    }
    mylist.pop_front();
  }
}
Example #3
0
void HCTree::encodeHelper(HCNode *curr, BitOutputStream& out) {
    if (curr->p == 0) return;
    encodeHelper(curr->p, out);
    if (curr->p->c0 == curr) out.writeBit(0);
    else out.writeBit(1);
    bitCount++;
}
Example #4
0
int main( int argc, char* argv[] )
{
   if( argc != 3 )
   {
      cerr << "Usage: " << argv[0] << " infile outfile." << endl;
      return -1;
   }

   errno = 0;
   ifstream in;
   in.open( argv[1], ios::binary );
   if( errno )
   {
      cerr << "Error in " << argv[1] << ": " << strerror( errno ) << endl;
      return -1;
   }

   ofstream out;
   out.open( argv[2], ios::binary );
   if( errno )
   {
      cerr << "Error in " << argv[2] << ": " << strerror( errno ) << endl;
      in.close();
      return -1;
   }

   vector<int>* freqs = new vector<int>( 256, 0 );
   BitInputStream* input = new BitInputStream( in );
   BitOutputStream* output = new BitOutputStream( out );
   
   int msgCnt = input->readInt();
   int symCnt = input->readInt();
   for( int i = 1; i <= symCnt; i++ )
   {
      int c = input->readByte();
      int cCnt = input->readInt();
      freqs->at( c ) = cCnt;
   }

   HCTree* decodeTree = new HCTree();
   decodeTree->build( *freqs );
   input->fill();
   for( int i = 0; i < msgCnt; i++ )
   {
      output->writeByte( decodeTree->decode( *input ) );
   }
   in.close();
   out.close();

   delete output;
   delete decodeTree;
   delete input;
   delete freqs;
   return 0;
}
Example #5
0
void HCTree::encode(byte symbol, BitOutputStream& out) const
{
	std::string code = getCode(symbol);
	for (size_t i = 0; i < code.size(); ++i) {
		if (code[i] == '1') {
			out.writeBit(true);
		} else {
			out.writeBit(false);
		}
	}
}
void HCTree::encode (byte symbol, BitOutputStream& out) const {

	std::vector<int> code;
	// find the path to the leaf to make the code
	for (int i = 0; i < leaves.size(); i++) {
		if (leaves[i] != 0 && leaves[i]->symbol == symbol) {
			HCNode * node = leaves[i];
			while (node->p != 0) {
				if (node == node->p->c0) {
					code.push_back(0);
					node = node->p;
				}
				else if (node == node->p->c1) {
					code.push_back(1);
					node = node->p;
				}
			}
		}
	}	

	// write the code to the file
	for (int v = code.size() - 1; v >= 0 ; v--) {
		out.writeBit(code[v]);
	}
}
/** Write to the given BitOutputStream
  *  the sequence of bits coding the given symbol.
  *  PRECONDITION: build() has been called, to create the coding
  *  tree, and initialize root pointer and leaves vector.
  */
void HCTree::encode(byte symbol, BitOutputStream& out) const{ 
    // Assign node to inputed byte
    HCNode *leafSym= this -> leaves[symbol]; 
	
	// Build from top to bottom
    std::stack<int> st;

    //cout << "starting loop" << endl;
	while(leafSym != this->root && leafSym != NULL){

        if (leafSym -> p -> c0 == leafSym) {
            st.push(0);
        }

        else if (leafSym -> p -> c1 == leafSym) {
            st.push(1);
        }
        leafSym = leafSym-> p;

    } 

    while (!st.empty()) {
        out.writeBit( st.top());
        st.pop();
    }
}
Example #8
0
// Recursive function to write each bit in proper order
void writePattern(HCNode * node, BitOutputStream& out)
{
    if(node->p != NULL)
    {
	writePattern(node->p, out);
	out.writeBit(node->isChild1);
    }
    return;
}
Example #9
0
//Method that encodes the tree into an out file to be decoded later on
void HCTree::encode(byte symbol, BitOutputStream& out) const
{
  //Gets the certain code sequence of the current symbol
  std::string seq = getValue(symbol);

  //Writes the bits to the correct sequences
  for(size_t index = 0; index < seq.size(); index++)
  {
    if(seq[index] == '1')
    {
      out.writeBit(true);
    }
    else
    {
      out.writeBit(false);
    }
  }
}
/** Write to the given BitOutputStream
 *  the sequence of bits coding the given symbol.
 *  PRECONDITION: build() has been called, to create the coding
 *  tree, and initialize root pointer and leaves vector.
 */
void HCTree::encode(byte symbol, BitOutputStream& out) const{
  HCNode* temp = leaves[symbol];
  stack<int> codeStack;
  if (temp->p == 0){
    out.writeBit(0);
  }
  while (temp->p != 0) {
    if (temp->p->c0==temp) {
      codeStack.push(0);
    } else{
      codeStack.push(1);
    }
    temp=temp->p;
  }
  while(!codeStack.empty()){
    out.writeBit(codeStack.top());
    codeStack.pop();
  }
}
Example #11
0
/** Write to the given BitOutputStream
 *  the sequence of bits coding the given symbol.
 *  PRECONDITION: build() has been called, to create the coding
 *  tree, and initialize root pointer and leaves vector.
 */
void HCTree::encode(byte symbol, BitOutputStream& out) const {
  HCNode *pointer = leaves[symbol];
  std::stack<int> stk;
  while(pointer->p != 0) {
    if(pointer == pointer->p->c0) stk.push(0);
    else stk.push(1);
    pointer = pointer->p;
  }
  while(stk.size() != 0) {
    out.writeBit(stk.top());
    stk.pop();
  }
}
Example #12
0
void write_header(std::vector<int> freqs, BitOutputStream out)
{
    int size = 0;
    int char_length = 0;
    for(int i = 0; i < freqs.size(); i++)
    {
        if(freqs[i])
        {
            size++;
            char_length += freqs[i];
        }
    }
    out.writeByte(size);
    out.writeInt(char_length);
    
    for(int i = 0; i < freqs.size(); i++)
    {
        if(freqs[i])
        {
            out.writeByte(i);
            out.writeInt(freqs[i]);
        }
    }
}
Example #13
0
//Write char for length of code, char for ascII symbol, then bits for code
void HCTree::encode(byte symbol, BitOutputStream& out) const
{
    HCNode *currNode = leaves[symbol];
    //stack of int since writeBit takes in int parameter
    stack<int> bodyStack;
    stack<int> headerStack;
    //we can't go above root since it has no parent
    while (currNode != root){
        HCNode *parentNode = currNode->p;
        if (parentNode->c0 == currNode){
            //node is on the left side of the parent
           bodyStack.push(0);
        }else{
           bodyStack.push(1);
        }
        currNode = parentNode;
    }

    for (unsigned int i = 0; i < stack.size(); i++){
        int encodedBit = stack.top();
        out.writeBit(encodedBit);
        stack.pop(); //remove each element once it's written
    }
}
Example #14
0
int main(int argc,char **argv)
{
    //Check for arguments
    if(argc != 3) {
	cout << "Invalid number of arguments.\n" 
	<< "Usage: ./compress <input filename> <output filename>.\n";
	return -1;
    }

    //Check for file names
    if(!strcmp(argv[1],argv[2])) { 
	cerr << "Error: Same name for input and output files.\n"; 
	return -1; 
    }

    /** 1. Open the input file for reading. */
    ifstream in;
    in.open(argv[1],ios::binary);

    /**
    * 2. Read bytes from the file, counting the number of occurrences of
    * each byte value; then close the file.
    */
    vector<int> count(256,0);
    int ch;
    int isempty = 1;
    while(1) {
	ch = in.get();
	if(!in.good()) break;		// failure
	count[ch]++;			// read a char, count it
	isempty = 0;
    }

    if(isempty) {			// empty file
	ofstream out;
	out.open(argv[2],ios::binary);
	out.close();
	return 0;
    }

    if(!in.eof()) {			// loop stopped for some bad reason...
	cerr << "There was a problem, sorry." << endl; 
	return -1; 
    }
    in.close();

    /**
    * 3. Use these byte counts to construct a Huffman coding tree. Each 
    * unique byte with a non-zero count will be a leaf node in the Huffman tree.
    */
    HCTree Huffman;
    Huffman.build(count);
    
    /** 4. Open the output file for writing. */
    ofstream out;   
    out.open(argv[2],ios::binary);

    /**
    * 5. Write enough information to the output file to enable the coding
    * tree to be reconstructed when the file is read by your uncompress program.
    */   
    BitOutputStream os = BitOutputStream(out);
    int realcount = 0;
    for(int i=0;i<count.size();i++) {
	if (count[i]) realcount++;	//count for asciis that appear	
    }
    os.writeInt(realcount);		//print the number of asciis that appear
    os.writeByte('\n');
    for(int i=0;i<count.size();i++) {
	if (count[i]) {
	os.writeInt(i);
	os.writeByte(' ');
	os.writeInt(count[i]);
	os.writeByte('\n');
	}
    }

    /** 6. Open input file for reading again. */
    in.open(argv[1],ios::binary);

    /**
    * 7. Using the Huffman coding tree, translate each byte from the input
    * file into its code, and append these codes as a sequence of bits to
    * the output file, after the header.
    */
    char symbol;
    while(1) {
	symbol = in.get();
	if(!in.good()) break;
	Huffman.encode(symbol,os);
    }
    os.flush();

    /** 8. Close the input and output files. */
    in.close();
    out.close();
    return 0;
  }
int main(int argc, char** argv){
	if(argc != 3){
		cerr << "One file doesn't exist, sorry." << endl;
		return -1;
	}
	if(strcmp(argv[1],argv[2])==0){
		cerr << "Output file has the same name as input file, sorry." << endl;
		return -1;
	}
	int valid = 0;
	int onlychar;
	int total = 0;
	int isEmpty = 1;
	ifstream in;
	in.open(argv[1], ios::binary);
	ofstream out;
	out.open(argv[2], ios::binary);
	if(!in.good()){
		cerr << "The input file can't be opened or read from, sorry." << endl;
		return -1;
	}
	if(!out.good()){
		cerr << "The output file can't be written, sorry." << endl;
		return -1;
	}
	vector<int> count = vector<int>(256,0);
	unsigned char ch;
	while(1){
		ch = in.get();
		if(!in.good()) break;
		isEmpty = 0;
		count[ch]++;
		total++;
	}
	if(!in.eof()){
		cerr << "There was a problem, sorry." << endl;
		return -1;
	}
	if(isEmpty == 1){
		cerr << "The file is empty, sorry." << endl;
		return -1;
	}
	in.close();
	// ofstream out;
	// out.open(argv[2], ios::binary);
	BitOutputStream* a = new BitOutputStream(out);
	a->writeInt(total);

	for(int i=0;i<256;i++){
		if(count[i]){
			valid++;
			onlychar = i;
		}
	}
	if(valid==1){
		a->writeByte(1);
		a->writeByte(onlychar);
		out.close();
		return 0;
	}else{
		a->writeByte(0);
	}
	// for(int i=0;i<256;i++){
	// 	cout << i << " " << count[i] << endl;
	// }
	HCTree* tree = new HCTree();
	tree->build(count);
	for(int i=0;i<256;i++){
		a->writeByte(tree->leaf[i]);
	}
	for(int i=0;i<255;i++){
		a->writeByte(tree->intnode[i]);
	}
	for(int i=0;i<32;i++){
		a->writeByte(tree->leafchildbit[i]);
	}
	for(int i=0;i<32;i++){
		a->writeByte(tree->intnodechildbit[i]);
	}
	in.open(argv[1], ios::binary);
	//cout << "test" << endl;
	while(1){
		ch = in.get();
		if(!in.good()) break;
		tree->encode(ch, *a);
	}
	if(!in.eof()){
		cerr << "There was a problem, sorry." << endl;
		return -1;
	}
	if(a->get_buf_index()!=0){
		a->flush();
	}
	in.close();
	out.close();
	return 0;
}