/* Function: encodeTreeToFileHeader * -------------------------------- * Encodes tree shape into cypherFile. * Makes depth traversing of coding tree, and writes: * * - 0 - if it's knot at this traverse, without symbols * * - 1 - if it's leaf at this traverse, without childs. * It is followed by char byte code. */ void encodeTreeToFileHeader(Node* node, obstream& outfileStream) { /* This node is fork end * We should write '1' and char code then */ if ((node->leftChild == NULL) && (node->rightChild == NULL)) { outfileStream.writeBit(1); outfileStream.put((node->symbol)); }else{ /* This node has childs - we should write just '0' */ outfileStream.writeBit(0); if (node->leftChild != NULL) { encodeTreeToFileHeader((node->leftChild), outfileStream); } if (node->rightChild != NULL) { encodeTreeToFileHeader((node->rightChild), outfileStream); } } }
/* Function: decodeFileToFile * -------------------------- * Main cyphered text decoding process. */ void decodeFileToFile(ibstream& infileStream, Node* root, obstream& outfileStream) { int bit; Node* currentNode = root; /* Runs through every cypher bit and, at the same time, move * through tree to symbols leafs */ while ((bit = infileStream.readBit()) > -1) { if (bit == 0) { currentNode = currentNode->leftChild; }else{ currentNode = currentNode->rightChild; } if ((currentNode->symbol) < NOT_A_CHAR) { if (((char)currentNode->symbol) == EOF) { break; }else{ outfileStream.put((char)(currentNode->symbol)); } currentNode = root; } } }
bool Encoding::decompress(ibstream &inStream, obstream &outStream){ int mapSize = inStream.get(); char kill = inStream.get(); //get rid of pipe map<string, int> dmap; //remove this after testing for (int i = 0; i < mapSize; i++){ int code; string key; code = inStream.get(); int val = inStream.get(); while (val != '|'){ key += val; val = inStream.get(); } dmap[key] = code; } int input; string code; while (true){ code += IntegerToString(inStream.readbit()); if (dmap.count(code) > 0){ input = dmap[code]; //cout << input << endl; outStream.put(input); code.clear(); if (inStream.peek() == _EOF_) break; } } cout << " made it out of the loop"; outStream.close(); return true; }
/* Function: compress * Usage: compress(infile, outfile); * -------------------------------------------------------- * Main entry point for the Huffman compressor. Compresses * the file whose contents are specified by the input * ibstream, then writes the result to outfile. */ void compress(ibstream& infile, obstream& outfile) { /* Calculates the frequencies of each character within text */ Map<ext_char, int> frequenciesTable = getFrequencyTable(infile); /* Buffer-vector for cypher tree creation */ Vector<Node*> vec; /* Add nodes for each sumbol and put them to vec */ buildNodesVector(vec, frequenciesTable); /* Main Huffman tree building */ Node* root = buildEncodingTree(vec); /* ENCODE TREE INTO CYPHER FILE HEADER */ encodeTreeToFileHeader(root, outfile); outfile.put(' ');//put some char to divide header from main text cypher /* ENCODE FILE MAIN TEXT INTO CYPHER FILE */ infile.rewind(); encodeMainTextToFile(infile, root, outfile); /* Memory cleaning */ deleteTree(root); }
bool Encoding::compress(ibstream &inStream, obstream &outStream){ buildEncodingForInput(inStream); int input; string code; map<int, string>::iterator it; outStream.put(mp.size()); outStream.put('|'); for (it = mp.begin(); it != mp.end(); it++){ outStream.put(it->first); //cout << it->first << " has the code "; for (int i = 0; i < it->second.size(); i++){ outStream.put(it->second[i]); //cout << it->second[i]; } outStream.put('|'); //cout << endl; } inStream.rewind(); string temp; int letter; int temps; for (int i = 0; i < inStream.size(); i++){ temps = inStream.size(); input = inStream.get(); code = mp[input]; for (int i = 0; i < code.length(); i++){ temp = code[i]; outStream.writebit(StringToInteger(temp)); //cout << code[i]; } //cout << endl; } outStream.put(_EOF_); outStream.close(); return true; }