HuffmanTree* HuffmanEncoder::huffmanTreeFromFrequencyMap(uint64_t *FreqMap) { priority_queue<HuffmanTree*,vector<HuffmanTree*>,HuffmanTreeCompare> forest{}; for (int i = 0; i < 256; i++) { if (FreqMap[i] == 0) { continue; } HuffmanTree *tree = new HuffmanTree((char)i, FreqMap[i]); if (tree->GetWeight() == 0) { printf("Weight is 0!!!********************************************************8\n"); } forest.push(tree); } printf("%ld trees in forest", forest.size()); while (forest.size() > 1) { HuffmanTree *smallest = forest.top(); forest.pop(); HuffmanTree *secondSmallest = forest.top(); forest.pop(); HuffmanTree *tree = new HuffmanTree(smallest, secondSmallest); forest.push(tree); } return forest.top(); }
int main(int argc, char* argv[]) { using namespace ptlmuh006; if(argc != 4){ std::cout << "Incorrect usage." << std::endl; std::cout << "Please use huffencode as follows:" << std::endl; std::cout << "huffencode <option> <inputFilename> <outputFilename>" << std::endl; std::cout << "\t___options:___" << std::endl; std::cout << "\t -c compress data from inputFilename to outputFilename" << std::endl; std::cout << "\t -x extract compressed data from inputFilename to outputFilename" << std::endl; }else{ HuffmanTree* huff = new HuffmanTree; std::string option = argv[1]; if(option == "-c"){ huff->compress(argv[2], argv[3]); std::cout << "Compressed " << argv[2] << " into " << argv[3] << "." << std::endl; }else if(option == "-x"){ huff->extract(argv[2], argv[3]); std::cout << "Extracted from " << argv[2] << " into " << argv[3] << "." << std::endl; } delete huff; } return 0; }
void TextEncryptor::processInputStream(istream& input) { char c; bitset<8> outputSymbol; string pattern; while (input.get(c)) { pattern += ht->getEncodingForSymbol(c); while ( pattern.length() >= 8) { outputSymbol = bitset<8>(pattern.substr(0, 8)); char i = (char)outputSymbol.to_ulong(); operator << (binaryOutput, i); pattern.erase(0, 8); } } // If last byte is not completely filled up, // we append bits from white space sysmbol until the end of the last byte... if (pattern.length() > 0) { string& strWhiteSpace = ht->getEncodingForSymbol(' '); size_t curSpaceBit = 0; while (pattern.length() < 8) { pattern += strWhiteSpace[ curSpaceBit++ % strWhiteSpace.length() ]; } outputSymbol = bitset<8>(pattern); char i = (char)outputSymbol.to_ulong(); operator << (binaryOutput, i); } }
void Test() { int w[] = {5,29,7,8,14,23,3,11}; HuffmanTree *ht = new HuffmanTree(); ht->huffmanInit(w, 8); ht->printTree(15); ht->createHuffmanCode(8); ht->printCode(8); }
HuffmanTree* HuffmanEncoder::huffmanTreeFromMap(vector<string> huffmanMap) { //Generates a Huffman Tree based on the supplied Huffman Map.Recall that a //Huffman Map contains a series of codes(e.g. 'a' = > 001).Each digit(0, 1) //in a given code corresponds to a left branch for 0 and right branch for 1. HuffmanTree *tree = new HuffmanTree(new HuffmanInternalNode(NULL, NULL)); for (int i = 0; i < 256; i++) { char c = (char) i; string code = huffmanMap[i]; if (code.length() == 0) continue; HuffmanInternalNode *n = (HuffmanInternalNode*)tree->GetRoot(); for (unsigned int j = 0; j < code.length() -1; ++j) { if (code[j] == '0') { if (n->GetLeftChild() != NULL) { n = (HuffmanInternalNode*) n->GetLeftChild(); } else { n->SetLeftChild(new HuffmanInternalNode(NULL, NULL)); n = (HuffmanInternalNode*) n->GetLeftChild(); } } else { if (n->GetRightChild() != NULL) { if (n->IsLeaf()) { //tree->Print(); exit(1); } n = (HuffmanInternalNode*) n->GetRightChild(); } else { n->SetRightChild(new HuffmanInternalNode(NULL, NULL)); n = (HuffmanInternalNode*) n->GetRightChild(); } } } c = code[code.length() -1]; if (c == '0') { n->SetLeftChild(new HuffmanLeafNode((char)i, 0)); } else { n->SetRightChild(new HuffmanLeafNode((char)i, 0)); } } //printf("Tree created from map:\n"); //tree->Print(); return tree; }
int main(){ ifstream file; file.open("Amazon_EC2.txt"); if(!file.is_open()) cout << "File not found"; //Create a vector of freqs //256 for ascii values initialized to 0 vector<int> freq(256,0); int c; int count = 0; while(file.good()){ count++; c = file.get(); //End of file if(c < 0) continue; freq[c] = freq[c] + 1; } file.close(); /* for(int i = 0; i < freq.size(); i++){ if(freq[i] != 0){ double ratio = ((double)freq[i]/(double)count)*100; cout << (char)i << " " << ratio << endl; } } */ //Instantiate tree HuffmanTree tree; //Call create to make the tree tree.create(freq); //Create output file stream ofstream outputFile("compressedFile.txt",ios::out); stream out(outputFile); //Open file to get letters to compress with path ifstream file2; file2.open("Amazon_EC2.txt"); //Call compress to write bits of each letter to the file char z; while(file2.good()){ z = (char)file2.get(); tree.compress(z, out); } file2.close(); outputFile.close(); cout << endl << "Outputfile Created: compressedFile.txt" << endl << endl; return 0; }
int main( int argc, char* argv[] ) { if ( argc != 2 ) { cerr << "\n usage: " << argv[0] << " file\n\n"; return 1; } string exec = argv[0]; string fileName = argv[1]; bool compressFlag; exec.replace(0,exec.find_last_of('/')+1,""); // Get 'basename' of arg[0] if (exec == "compress") compressFlag = true; else compressFlag = false; if (compressFlag) { // Compress string compressedFile = fileName + ".hc"; CountTable ct(fileName.c_str()); HuffmanTree ht; ct.createCharMap(); //ct.printCharMap(); ct.buildNodeList(ht); //ht.printNodeList(); ht.buildTree(); //ht.printTree(); ht.genCharSeqTable(); //ht.printCharSeqTable(); CompressFile cf(fileName, compressedFile); //ht.printNodeList(); cf.doit(ht); } else { // Uncompress string compressedFile = fileName + ".hc"; string uncompressedFile = fileName + ".uc"; // CountTable ct(fileName); HuffmanTree ht; UncompressFile uf(compressedFile, uncompressedFile); uf.buildNodeList(ht); //ht.printNodeList(); ht.buildTree(); //ht.printTree(); //uf.printCompressedBits(); uf.doit(ht); } } // End Main()
int main() { HuffmanTree H; char c[50]; int n=0; H.Show(c,n); cout<<endl; cout<<"请输入01序列#结尾"<<endl; cin>>c; H.Translate(c); return 0; }
int main() { ifstream image; image.open("/home/cxy229/image/data.dat"); if(!image.good()) //文件未成功打开 { cerr<<" error:: unable to open image! "<<endl; exit(1); } char aaaa[4]={'a','b','c','d'}; int w[4]={5,6,7,8}; HuffmanTree<char> test; test.setTree(w,aaaa,4,0); test.encode(test.getroot(),""); cout<<"d:"<<test.coding('d')<<endl; cout<<"c:"<<test.coding('c')<<endl; cout<<"b:"<<test.coding('b')<<endl; cout<<"a:"<<test.coding('a')<<endl; cout<<test.uncoding("010110"); cout<<endl; imgCompressor img; img.run(); return 0; }
void imgCompressor::compresse()//图片压缩 { ofstream img_com("/home/cxy229/image/img_compressed",ios::app); if(!img_com) { cout<<" fail to open img_compressed"<<endl; exit(1); } ifstream image; image.open("/home/cxy229/image/data.dat",ios::in); if(!image.good()) //文件未成功打开 { cerr<<" error:: unable to open image! "<<endl; exit(1); } char temp[65]; string str = ""; int k = 0; while(!image.eof()) { image.getline(temp,65); for(k = 0; k < 64; k += 8) { str = swich(temp + k, 8); img_com<<h_tree.coding(str);//将压缩后的编码写入文件 } img_com<<endl; } image.close(); img_com.close(); }
void imgCompressor::decompresse() { ifstream img_com; img_com.open("/home/cxy229/image/img_compressed"); if(!img_com.good()) //文件未成功打开 { cerr<<" error:: unable to open img_compressed! "<<endl; exit(1); } ofstream img_decom("/home/cxy229/image/img_decompressed",ios::out|ios::app); if(!img_decom) { cout<<" fail to open img_decom"<<endl; exit(1); } char temp[100]; string str; while(!img_com.eof()) { img_com.getline(temp,99); str = swich(temp,strlen(temp)); //cout<<str; img_decom<<h_tree.uncoding(str)<<endl; } img_com.close(); img_decom.close(); }
void UncompressFile::doit(HuffmanTree& ht) { if (!osPtr.is_open()) { // Open file osPtr.open(outFile.c_str()); if (!osPtr) { cerr << "Error: Could not open: '" << outFile << "' for writing" << endl; return; } } unsigned char c; while (true) { c = ht.getChar(getBit()); if (c < (unsigned char)'\x80') { // if ( c > ' ' ) printf("'%c'\n", c); // else printf("'%02x'\n", c); osPtr.put(c); continue; } else if (c == (unsigned char)EOF) { break; } else if (c == (unsigned char)'\xf0') { // Not there yet continue; } else if (c == (unsigned char)'\xf1') { cout << "uncompress() : Internal Error\n"; break; } } if ( isPtr.is_open()) isPtr.close(); if ( osPtr.is_open()) osPtr.close(); } // End doit()
string HuffmanEncoder::decodeBits(vector<bool> bits, vector<string> huffmanMap) { HuffmanTree *tree = HuffmanEncoder::huffmanTreeFromMap(huffmanMap); vector<string> map = HuffmanEncoder::huffmanEncodingMapFromTree(tree); HuffmanEncoder::writeEncodingMapToFile(map, "encmap.map"); HuffmanNode *n = tree->GetRoot(); ostringstream result{}; uint64_t last_index = 0; string stack; int num_decoded = 0; //tree->Print(); for (auto it = bits.begin(); it != bits.end(); ++it) { bool bit = *it; if (bit == false) { stack += "0"; n = ((HuffmanInternalNode*)n)->GetLeftChild(); } else { stack += "1"; n = ((HuffmanInternalNode*)n)->GetRightChild(); } if (n->IsLeaf()) { result << ((HuffmanLeafNode*)n)->GetValue(); num_decoded++; n = tree->GetRoot(); stack = ""; } last_index++; } /* TODO: perhaps the priority queue is different for each? That might * explain it. Compare frequencies, that can't be wrong. Issue is we have * different huffman maps on each run. Although, that might not be a problem * on write. The files are slightly different, make sure it's writing to a * good offset. Maybe try writing/reading garbage from that spot or * something, print out the first few chars, idk. Print where the offsets * and such are. Figure out exactly what is going where and if the way it's * getting compressed/decompressed differently is a problem. */ return result.str(); }
void addCharacter(HuffmanTree& T,int c,Writer& w) { T.writeCode(T.getLeaf(c),w); if (T.getLeaf(c)==T.getLeaf(NYT)) { //cout << c; w.writeNine(c); T.splitNYT(T.getLeaf(NYT),c); } T.updateBlockFirst(); T.updateTree(T.getLeaf(c)); //cout << (T.getRoot())->getWeight() << endl; }
int main(int argc, char* argv[]) { if (argc < 4) { cerr << "please provide an appropriate flag (-compress/-decompress) and two file names." << endl; return -1; } HuffmanTree tree; ifstream in(argv[2], ios::in | ios::binary); ofstream out(argv[3], ios::out | ios::binary); if (strcmp(argv[1], "-compress") == 0) { tree.encode(in, out); } else if (strcmp(argv[1], "-decompress") == 0) { tree.decode(in, out); } return 0; }
//------------------------------------------------------------------------------------------------- bool Huffman::createTable(std::vector<unsigned int> symbols, std::vector<unsigned int> counts) { HuffmanTree tree; // Tree for creating the table // Build the tree tree.buildTree(symbols, counts); // Get the table from the tree if(! tree.getTable((*m_pSymbols), (*m_pCodes))) { std::cerr << "Error in createTable: tree is empty" << std::cout; return false; } //Sort the table by code length for faster average lookup sortTable(); return true; }
int main() { string line; ifstream f("Huffman.txt"); getline(f, line); HuffmanTree* ht = new HuffmanTree(line); cout << "original message: " << line << "\n\n"; ht->buildTable(); ht->buildHeap(); ht->displayFreqTable(); ht->displayHuffTable(); ht->writeEncodedString(); ht->decodeHuffman(); ht->writeDecodedString(); ht->compressEncodedString(); ht->decompress(); system("pause"); return 0; }
void BinaryDecryptor::processInputStream(istream& input) { string currentEncoding; char desiredSymbol; char inputChar; bitset<8> inputBits; while (input.get(inputChar)) { inputBits = inputChar; string inputString = inputBits.to_string(); for (size_t i = 0; i < 8; ++i) { currentEncoding += inputString[i]; if (ht->containsEncodingPattern(currentEncoding)) { desiredSymbol = ht->getCharFromPattern(currentEncoding); textOutput << desiredSymbol; currentEncoding.clear(); } } } }
std::unordered_map<char, std::string> HuffmanTree::compress_file(std::string inputFile, std::string outputFile) { // variables and typedef typedef HuffmanTree::HuffmanNode node_type; HuffmanTree tree; std::unordered_map<char, unsigned int> map; std::unordered_map<char, std::string> code_table; std::priority_queue<node_type,std::vector<node_type>, HuffmanTree::Compare> prior_q; // calling methods tree.create_map(map,inputFile); tree.fill_queue(prior_q,map); HuffmanTree::HuffmanNode node(tree.build_tree(prior_q)); tree.generate_code_table(node,code_table,""); tree.generate_code_file(outputFile, code_table); std::string bit_string = tree.generate_bit_string(inputFile,code_table); tree.generate_binary_compressed_file(outputFile, bit_string); tree.generate_compressed_file(outputFile, bit_string); return code_table; }
HuffmanTree *HuffmanTreeFactory::BuildTree(u32 code_symbols) { if (_heap.size() < 1) return 0; while (_heap.size() > 1) { HuffmanTreeNode *branch = new HuffmanTreeNode; CAT_OBJCLR(*branch); ProbabilityType probability_sum = 0.; // For each code symbol, for (u32 ii = 0; ii < code_symbols; ++ii) { HuffmanTreeNode *leaf = _heap.top(); _heap.pop(); branch->children[ii] = leaf; probability_sum += leaf->probability; if (_heap.empty()) break; } branch->probability = probability_sum; // Push the combined branch back on the heap _heap.push(branch); } HuffmanTreeNode *root = _heap.top(); _heap.pop(); HuffmanTree *tree = _tree; tree->Initialize(code_symbols, root); _tree = 0; return tree; }
void decode() { int nCasos; string encoded_text, plain_text; cout << "decoding..." << endl; cin >> nCasos; cin.ignore(); for (int i = 0; i < nCasos; i++) { // Leer el texto codificado getline(cin, encoded_text); // Leer y reconstruir el árbol de huffman, que viene inorden // NOTA: tengo que distinguir entre HuffmanBranch y HuffmanLeaf HuffmanTree* ht = HuffmanReader::read(); cout << ht->to_string() << endl; // Una vez que tenemos el texto y el árbol, decodificarlo plain_text = Huffman::decode(encoded_text, *ht); cout << plain_text << endl; //delete ht; } }
void UncompressFile::buildNodeList(HuffmanTree& ht) { if ( !isPtr.is_open()) { isPtr.open(inFile.c_str()); if (!isPtr) { cerr << "Error: Could not open: '" << inFile << "' for reading" << endl; return; } } // char readBuf[readBufSize]; isPtr.getline((char*)readBuf,readBufSize); string buf; // Have a buffer string vector<string> token; stringstream ss((char*)readBuf); unsigned int count; // Tokenize the string into a vector while (ss >> buf) { token.push_back(buf); count++; } // Validate that we have a even number if (count % 2 != 0) { cerr << "CountTable::extractCharMap() : Internal Error\n"; return; } unsigned int c; // Convert the first token to 'hex' and the second to 'unsigned' for (unsigned i=0; i<token.size(); i+=2) { istringstream hex_char(token[i]); hex_char >> hex >> c; istringstream int_char(token[i+1]); int_char >> count; ht.buildNodeList(c, count); } if (isPtr.is_open()) isPtr.close(); } // End buildNodeList()
TableInfo phuffman::utility::BuildTable(InputIterator first, InputIterator last, Codes& table) { using namespace std; typedef DepthCounterNode Node; typedef multimap<size_t, Node*> HuffmanTree; typedef vector<Node*> Nodes; assert(distance(first, last) <= constants::MAXIMUM_DATABLOCK_SIZE); assert(table.size() >= constants::ALPHABET_SIZE); HuffmanTree tree; Nodes leafs; TableInfo info; // Initialize tree { Frequencies frequencies = CountFrequencies(first, last); Frequencies::const_iterator first = frequencies.begin(), last = frequencies.end(); while (first != last) { Node* leaf = new Node(first->symbol); tree.insert(make_pair(first->frequency, leaf)); leafs.push_back(leaf); ++first; } } // Build tree { for (size_t i=0, size=tree.size(); i<size-1; ++i) { HuffmanTree::iterator first = tree.begin(), second = tree.begin(); ++second; size_t freq = first->first + second->first; // Calculate freq for a node Node* node = new Node(first->second, second->second); ++second; tree.erase(first, second); // Remove two nodes with the smallest frequency tree.insert(make_pair(freq, node)); // Add node that points to previosly removed nodes } assert(tree.size() == 1); } // Count codelengths // In fact, codelengths are already counted in the 'depth' member of a node // There is only one exception: if the tree contains only one object, we need to set it's depth manually Node* root = tree.begin()->second; root->depth = 1; // Sort nodes by codelength sort(leafs.begin(), leafs.end(), TreeComparator); // Build table { Nodes::const_iterator first = leafs.begin(), last = leafs.end(); Node *curNode = *first; info.maximum_codelength = curNode->depth; Code curCode = CodeMake(curNode->depth, 0); table[curNode->element] = curCode; ++first; while (first != last) { assert(curNode->depth >= curCode.codelength); curNode = *first; // If current codeword and next codeword have equal lengths if (curNode->depth == curCode.codelength) { // Just increase codeword by 1 curCode.code += 1; } // Otherwise else { // Increase codeword by 1 and _after_ that shift codeword right curCode.code = (curCode.code + 1) >> (curNode->depth - curCode.codelength); } curCode.codelength = curNode->depth; table[curNode->element] = curCode; ++first; } } delete root; return info; }
void FileCompress::Uncompress(const char* filename) { HuffmanTree ht; int size = 0; //从配置文件中获取字符信息 string filenameconfig = filename; filenameconfig += ".config"; FILE* fout = fopen(filenameconfig.c_str(),"r"); assert(fout); unsigned char ch = fgetc(fout); long long sum = 0; while (!feof(fout)) { _infos[ch]._ch = ch; size++; char num = fgetc(fout); num = fgetc(fout); _infos[ch]._count = num - '0'; sum += _infos[ch]._count; ch = fgetc(fout); ch = fgetc(fout); } fclose(fout); //建树 CharInfo invaild; //ReadConfig(filename, _infos); ht.CreateTree(_infos, size,invaild); //从压缩文件取值遍历 string filenamecom = filename; filenamecom += ".com"; FILE* fin = fopen(filenamecom.c_str(),"r"); assert(fin); string filenameuncom = filename; filenameuncom += ".uncom"; fout = fopen(filenameuncom.c_str(), "w"); assert(fout); HuffmanTreeNode<CharInfo>* temp = ht.GetRoot(); ch = fgetc(fin); int count = 0; unsigned int t = 1; while ( !feof(fin))//sum != 0) { int x = 0; for (int i = 7; i >= 0; i--) { x = ch & (t << 7); if ((char)ch == EOF) { cout << 1; } ch <<= 1; if (x == 0) temp = temp->_left; else if (x == 0x80) temp = temp->_right; if (temp->_left == NULL && temp->_right == NULL) { fputc(temp->_weight._ch, fout); //sum--; cout << temp->_weight._ch; temp = ht.GetRoot(); x = 0; } } ch = fgetc(fin); } fclose(fin); fclose(fout); }
void FileCompress::Compress(const char* filename) { HuffmanTree mh; int size = Get_infos_Com(filename); //建树 CharInfo invaild; mh.CreateTree(_infos, size,invaild); //编码 string code; GenerateHuffmanCode(mh.GetRoot(), code); //配置文件 string filenameConfig = filename; filenameConfig += ".config"; FILE* fout = fopen(filenameConfig.c_str(), "wb"); assert(fout); for (int i = 0; i < 256; i++) { if (_infos[i]._count != 0) { fputc(_infos[i]._ch, fout); fputc(',', fout); fputc(_infos[i]._count+'0',fout); fputc('\n',fout); } } fclose(fout); //WriteConfig(filename); FILE* fin = fopen(filename, "r"); unsigned char ch = fgetc(fin); string filenamecom = filename; filenamecom += ".com"; fout = fopen(filenamecom.c_str(), "w+"); assert(fout); unsigned char value = 0; int pos = 7; while (!feof(fin)) { if (ch == '\r') { ch = fgetc(fout); if (ch != '\n') { fseek(fout, -1, SEEK_CUR); } } string& code = _infos[ch].code; int d = 0; for (int i = 0; i < code.size(); i++) { value <<= 1; if ((code[i] - '0') & (1)) { value |= 1; } else { value |= 0; d = 1; } pos--; if (pos == -1) { fputc(value, fout); if (d = 0) { cout << 1; } value = 0; d = 0; pos = 7; } } ch = fgetc(fin); } if (pos != -1) { for (int i = 0; i <= pos; i++) { value <<= 1; } fputc(value, fout); } fclose(fin); fclose(fout); }
int main() { string text; bool BeingInit = 0, BeingEncode = 0; HuffmanTree *tree; char *c; int *value; int n; int select; while (true) { cout << "1.initialization" << endl; cout << "2.write text to file" << endl; cout << "3.Encoding" << endl; cout << "4.Decoding" << endl; cout << "5.Print CodeFile" << endl; cout << "6.TreePrinting" << endl; cout << "7.show The Huffman code" << endl; cout << "8.exit" << endl; cin >> select; switch (select) { case 1: int t; cout << "1.build a new HuffmanTree" << endl; cout << "2.load from the file" << endl; cin >> t; while (true) { if (t == 1) { cout << "输入字符个数:"; cin >> n; c = new char[n]; value = new int[n]; for (int i = 0; i<n; i++) { cout << "第" << i + 1 << "个字符:"; cin >> c[i]; cout << "第" << i + 1 << "个权值:"; cin >> value[i]; } tree = new HuffmanTree(value, n, c); break; } if (t == 2) { tree = new HuffmanTree; break; } } cout << "initialization success!" << endl; BeingInit = 1; tree->save(); break; case 2:cout << "input your text: "; cin >> text; tree->writefile(text); cout << "OK!" << endl; break; case 3:if (!BeingInit) { cout << "the tree is not exist" << endl; break; } tree->Encoding(); cout << "succeed in encoding!" << endl; BeingEncode = 1; break; case 4:if (!BeingInit) { cout << "the tree is not exist" << endl; break; } if (!BeingEncode) { cout << "the tree haven't been encode, you must encoding before!" << endl; break; } tree->Decoding(); cout << "succeed in decoding!" << endl; break; case 5:if (!BeingInit) { cout << "the tree is not exist" << endl; break; } if (!BeingEncode) { cout << "the tree haven't been encode, you must encoding before!" << endl; break; } tree->Print(); cout << endl; break; case 6:if (!BeingInit) { cout << "the tree is not exist" << endl; break; } tree->printing(); break; case 7:tree->Huffmancode(); cout << endl; break; case 8:exit(0); default:break; } }
void imgCompressor::buildTree() { h_tree.setTree(wei,color,sum,""); h_tree.encode(h_tree.getroot(),""); }
int main(int argc, char ** argv) { if (argc != 4) // 检查参数数量 { showUsage(); return 1; } else { filename = argv[1]; // 判断文件名的后缀是不是 ".hfm" if (string(".hfm") != filename.substr(filename.length()-4, 4)) { fprintf(stderr, "输入文件的后缀不是 .hfm 。\n"); return 1; } treeFilename = argv[2]; sscanf(argv[3], "%lu", &bitLength); } // 载入哈夫曼树 HuffmanTree tree; tree.loadFromFile(treeFilename.c_str()); // 构造映射表 // 映射表是将字符映射到一个二进制序列的表 constructMapping(&tree, vector<int>()); // 打开待解码的文件 iBitFile bin((filename).c_str()); // 打开输出的文件 // file 定义在了本文件头部,为了方便函数 commitBuffer 而调整。 file = fopen((filename.substr(0, filename.length()-4)).c_str(), "wb"); // 解码 HuffmanTree * p = &tree; for (size_t i=0; i<bitLength; ++i) { int bit = bin.readNextBit(); p = p->childs[bit]; if (p == NULL) { fprintf(stderr, "待解码文件和树文件似乎不是对应的。"); return 1; } if (p->key != -1) { writeToBuffer((unsigned char)p->key); p = &tree; } } commitBuffer(bufferpos); fclose(file); bin.close(); fflush(stdout); return 0; }
#define CATCH_CONFIG_MAIN #include "catch.hpp" #include <fstream> #include <iostream> #include <sstream> #include <stdio.h> #include <unordered_map> #include "huffman.h" using namespace ptlmuh006; TEST_CASE("Files correctly compressed", "[compression]") { HuffmanTree huff; SECTION("Frequency table corectly generated") { //GIVEN: A string of data std::string data = "aaabbbccc dddddddddd\nccc"; //WHEN: We count the frequency of the characters in the string of data std::unordered_map<char, int> freqTbl = huff.countFrequency(data); //THEN: We should get a correct frequency table with characters mapped to tallys REQUIRE( freqTbl.size() == 6 ); REQUIRE( freqTbl['a'] == 3 ); REQUIRE( freqTbl['b'] == 3 ); REQUIRE( freqTbl['c'] == 6 ); REQUIRE( freqTbl[' '] == 3 ); REQUIRE( freqTbl['d'] == 10 ); REQUIRE( freqTbl['\n'] == 1 );
bool Compress::compress() { File * f = new File(m_path, m_fileName); QByteArray qba = f->read(); if (qba != NULL) { CountOccurrence * co = new CountOccurrence(qba); QList<Occurrence> occur = co->orderByOccurrence(); HuffmanTree * cht = new HuffmanTree(occur); Tree * tree = cht->createTree(); tree->createRep(); cht->createHash(tree); QString data; for (int i = 0; i < qba.size(); ++i) { QString pathNode = cht->hash()->value(qba.at(i)); data.append(pathNode); } int garbageSize = 8 - data.size()%8; if (garbageSize == 8) { garbageSize = 0; } for (int i = 0; i < garbageSize; ++i) { data.append("0"); } QBitArray toByte; toByte.resize(data.size()); for (int i = 0; i < data.size(); ++i) { if (data.at(i) == '0') { toByte[i] = true; } else { toByte[i] = false; } } bool ok; QByteArray encoded; QString c; for (int i = 0; i < data.size(); i+=8) { QString h = data.mid(i,8); encoded.append(QChar(h.toInt(&ok, 2))); c.append(h); } QString binaryGarbageSize = QString::number(garbageSize,2); QString binaryTreeSize = QString::number(tree->rep().size(),2); int zeros = 16 - (binaryGarbageSize.size() + binaryTreeSize.size()); for (int i = 0; i < zeros; ++i) { binaryTreeSize.prepend(QString::number(0)); } QString toBit = binaryGarbageSize; toBit.append(binaryTreeSize); int h1 = toBit.mid(0,8).toInt(&ok, 2); int h2 = toBit.mid(8,8).toInt(&ok, 2); QByteArray toWrite; toWrite.clear(); toWrite.append(QChar(h1)); toWrite.append(QChar(h2)); toWrite.append(m_fileName); for (int i = m_fileName.size(); i < 128; ++i ) { toWrite.append("#"); } toWrite.append(tree->rep()); toWrite.append(encoded); f->write(toWrite, m_path + m_compressedFileName); qDebug() << m_fileName << " comprimido"; return true; } else { qDebug() << "Arquivo não encontrado"; return false; } }