/** 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); } } }
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(); } }
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++; }
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; }
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(); } }
// 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; }
//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(); } }
/** 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(); } }
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]); } } }
//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 } }
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; }