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]); } } }
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; }