// encoder void Huffman::encode() { cout << "Begin encoding..." << endl; cout << "Open file..." << endl; inFile_.open(inFileName_.c_str(),ios::in); cout << "Calculating frequency of all ascii chars..." << endl; createNodeArray(); cout << "Done!" << endl; inFile_.close(); cout << "Creating Priority-Queue..." << endl; createPq(); cout << "Done!" << endl; cout << "Creating Huffman-Tree..." << endl; createHuffmanTree(); cout << "Done!" << endl; cout << "Calculating Huffman-Code..." << endl; calculateHuffmanCode(); cout << "Done!" << endl; cout << "Saving to outputfile..." << endl; saveToFile(); cout << "Done!" << endl; cout << "Ecoding finished!" << endl; }
bool huffmanPrintCode(Stream& in, Stream& out, bool verbose) { bool bOk = true; // check for the binnary header if(in.mode() == StreamRead && out.mode() == StreamWrite) { if(isHuffmanFile(in)) { // An Encoded file if(verbose) { fprintf(stdout, "huffmanPrintCode: encoded file\n"); } uint32_t dataBytes; HuffmanNode* root = readCodeTable(in, dataBytes); assert(root); SymbolEncoder SE; SE.buildSymbolEncoder(root); SE.printCodeTable(out); bOk = true; } else { // A natural File if(verbose) { fprintf(stdout, "huffmanPrintCode: natural file\n"); } FrequencyTable freqTable; SymbolEncoder SE; freqTable.updateFreqTable(in); calculateHuffmanCode(freqTable, SE); SE.printCodeTable(out); bOk = true; } } else { bOk = false; } return bOk; }
bool huffmanProcess(Stream& in, Stream& out, HuffmanDirection direction, bool verbose) { bool bOk = true; if(direction == HuffmanEncode) { FrequencyTable freqTable; SymbolEncoder SE; if(verbose) fprintf(stdout, "Encode\n"); { // Get the frequency of each symbol in the input file. freqTable.updateFreqTable(in); if(verbose) fprintf(stdout, "Input Size(%ld bytes)\n", freqTable.totalCount()); if(verbose) fprintf(stdout, "Nb symbols: %ld\n", freqTable.numberOfSymbols()); // Build an optimal table from the symbolCount. bOk = calculateHuffmanCode(freqTable, SE); double bitSize = 0.0; double entropy = 0.0; if(bOk) { computeAverageBitSize(SE, freqTable.totalCount(), bitSize, entropy, verbose); // Scan the file again and, using the table // previously built, encode it into the output file. in.rewind( ); } if(verbose) fprintf(stdout, "Writing code table (%lu symbols, %lu worlds)\n", freqTable.size(), freqTable.totalCount()); bOk = bOk ? SE.writeCodeTable(out, freqTable.totalCount()) : false; if(bOk) { if(verbose) fprintf(stdout, "Encoding\n"); bOk = SE.encode(in, out, verbose); } // Print info fprintf(stdout, "Encoded: nbSymbol: %ld, bitSize: %.2g, entropy: %.2g, nbBytes: %ld\n", freqTable.numberOfSymbols(), bitSize, entropy, freqTable.totalCount()); } } else { if(verbose) fprintf(stdout, "Decode File"); unsigned int totalNbBytes = 0; // Read the Huffman code table. fprintf(stdout, "# Reading code table"); std::auto_ptr<const HuffmanNode> root(readCodeTable(in, totalNbBytes)); if(!root.get()) { fprintf(stdout, "Error: cannot read code table\n"); bOk = false; } else { if(verbose) fprintf(stdout, "# Decoding (size: %u bytes)", totalNbBytes); // Decode the file. const HuffmanNode* p = root.get(); unsigned int remainingNbBytes = totalNbBytes; unsigned int totalCountOfSymbols = 0; while(remainingNbBytes>0 && in.isOpen()) { const Byte byte = in.readByte(); Byte mask = 1; while(remainingNbBytes>0 && mask) { p = (byte & mask) ? p->one() : p->zero(); mask <<= 1; assert(p); if(p->isLeaf( )) { out.writeSymbol(p->symbol()); totalCountOfSymbols++; p = root.get(); --remainingNbBytes; } } } // this is not needed for the decode - Just for the info section SymbolEncoder SE; SE.buildSymbolEncoder(root.get()); double bitSize = 0.0; double entropy = 0.0; computeAverageBitSize(SE, totalCountOfSymbols, bitSize, entropy, verbose); fprintf(stdout, "Decoded: nbSymbol: %ld, bitSize: %.2g, entropy: %.2g, nbBytes: %u\n", SE.nbSymbol(), bitSize, entropy, totalNbBytes); } } if(verbose) fprintf(stdout, "done (%d).\n", bOk); return bOk; }