void HuffTree::makeCodes(map<int, string> &codes, HuffNode * node, string code, bool side) { if (node == nullptr) { return; } string tmpCode = code; if (side == false) { tmpCode += "0"; node->setCode().resize(tmpCode.size() - 1); copy(tmpCode.begin() + 1, tmpCode.end(), node->setCode().begin()); } else { tmpCode += "1"; node->setCode().resize(tmpCode.size() - 1); copy(tmpCode.begin() + 1, tmpCode.end(), node->setCode().begin()); } if (node->getLeft() == nullptr && node->getRight() == nullptr) { if (node->getCode() == "") { node->setCode() += "0"; } codes.insert(make_pair(node->getChar(), node->getCode())); } makeCodes(codes, node->getLeft(), tmpCode, false); makeCodes(codes, node->getRight(), tmpCode, true); }
void makeCodes(Symbol *root) { if (root->left) { strcpy(root->left->code, root->code); strcat(root->left->code, "0"); makeCodes(root->left); } if (root->right) { strcpy(root->right->code, root->code); strcat(root->right->code, "1"); makeCodes(root->right); } }
void DynFMI::makeCodes(ulong code, int bits, WaveletNode *node){ #ifndef NDEBUG if (node == node->left) { cout << "makeCodes: autsch" << endl; exit(0); } #endif if (node->left) { makeCodes(code | (0 << bits), bits+1, node->left); makeCodes(code | (1 << bits), bits+1, node->right); } else { codes[node->c0] = code; codelengths[node->c0] = bits+1; } }
void Huffman::makeCodes(struct Node* root, string str, map<char32_t, string>& huffmanCodes) { if (!root) return; if (root->data != 0) { huffmanCodes.insert({root->data, str}); countOfOperations += 1; return; } makeCodes(root->left, str + "0", huffmanCodes); makeCodes(root->right, str + "1", huffmanCodes); countOfOperations += 6; }
void Huffman::startHuffman(map<char32_t, int>& letters, BitOutput*& writer, map<char32_t, string> &huffmanCodes) { struct Node* left, * right, * top; priority_queue<Node*, vector<Node*>, compare> queue; for (auto it = letters.begin(); it != letters.end(); ++it) { queue.push(new Node(it->first, it->second)); countOfOperations += 1; } while (queue.size() != 1) { left = queue.top(); queue.pop(); right = queue.top(); queue.pop(); top = new Node(0, left->freq + right->freq); top->left = left; top->right = right; queue.push(top); countOfOperations += 9; } root = queue.top(); makeCodes(root, "", huffmanCodes); encodeNode(root, writer); countOfOperations += 7; }
int makeCodes(nodeStructure* rootNode, int depth) { static char buff[0xFF]; if (rootNode->l == NULL && rootNode->r == NULL) { // leaf if (depth == 0) { buff[0] = '0'; buff[1] ='\0'; // single } else buff[depth] = '\0'; strcpy(codes[rootNode->c], buff); printf("%s - %c\n", buff, rootNode->c); depth--; return depth; } buff[depth] = '0'; makeCodes(rootNode->l, ++depth); buff[--depth] = '\0'; buff[depth] = '1'; makeCodes(rootNode->r, ++depth); buff[--depth] = '\0'; return depth; }
// Codifica uma entrada num arquivo binario utilizando a codificação de Shannon-Fano string encode(string *input, int *sizeB, int *sizeA) { std::vector<Symbol> symbols; unsigned short num_bit = 1; bool flag = false; string file = ""; if ((input != NULL) && (!input->empty())) { file = *input; flag = readFile(input); } if (flag) { *sizeB = input->size(); makeVector(*input,symbols); // Constroi o vector com os simbolos while (symbols.size() > pow(2,num_bit)) // Conta quantos bits serao necessarios para representar os simbolos num_bit++; makeCodes(symbols); // Cria os codigos em Shannon-Fano de cada simbolo string encoded = charToSF(*input,symbols); // String com a mensagem na codificação de Shannon-Fano input->clear(); string output = outArvore(symbols, encoded, input); // Saida do algoritmo de Shannon-Fano *sizeA = output.size(); writeOutput(output, &file); // Escreve a(s) saida(s) no arquivo // Limpando memoria symbols.clear(); // --------------- return output; } return ""; }
int main(int argc, char **argv) { int* freq = countChars(data, (int)strlen(data)); #ifdef DEBUG_MODE printInputCharTable(freq); puts(""); #endif nodeStructure** nodePointers = getFirstNodePointers(freq); int len =pointerCounter(nodePointers); #ifdef DEBUG_MODE printf("\nTotal: %d.\n\n", len); #endif nodeStructure *rootNode = makeTree(nodePointers, len); #ifdef DEBUG_MODE printf("\nrooot %p found.\n", rootNode); #endif #ifdef DEBUG_MODE // puts("\nnow backwards...\n"); // drawTree(rootNode); // puts("\n\ncodes:\n"); // printCodes(rootNode); #endif puts("\ncodes:\n"); makeCodes(rootNode, 0); // for(int i = 0; printf("%s\n", (char*)codes[i]), i < 0x100; i++); // it works! 😱 puts(""); printf("%s - %lu bytes\n", data, strlen(data)); bitStreamOut((int)strlen(data), data); puts(""); return 0; }
void DynFMI::initEmptyDynFMI(uchar *text){ // pointers to the leaves for select leaves = (WaveletNode**) new WaveletNode*[256]; for(int j=0; j<256; j++) leaves[j]=0; ulong i=0; while (text[i]!='\0') { if (leaves[text[i]]==0) { leaves[text[i]] = new WaveletNode(text[i]); } leaves[text[i]]->weight++; i++; } // separation symbol: leaves[0] = new WaveletNode((uchar)0); leaves[0]->weight=1; // Veli's approach: priority_queue< WaveletNode*, vector<WaveletNode*>, greater<WaveletNode*> > q; for(int j=0; j<256; j++){ if (leaves[j]!=0) { q.push( (leaves[j]) ); } codes[j] = 0; codelengths[j] = 0; } // creates huffman shape: while (q.size() > 1) { WaveletNode *left = q.top(); q.pop(); WaveletNode *right = q.top(); q.pop(); q.push( new WaveletNode(left, right) ); } root = q.top(); q.pop(); makeCodes(0,0, root); // writes codes and codelengths // merge leaves (one leaf represent two characters!) for(int j=0; j<256; j++){ if (leaves[j]) { if (leaves[j]->parent->left==leaves[j]) { leaves[j]->parent->c0=j; } else { leaves[j]->parent->c1=j; } leaves[j]=leaves[j]->parent; // merge } } deleteLeaves(root); appendBVTrees(root); // array C needed for backwards search for(int j=0; j<256+256; j++) C[j] = 0; }
// Cria os codigos de cada simbolo de acordo com Shannon-Fano void makeCodes(vector<Symbol> & s) { double x = 0, w = 0, a =0; short i = 0, j = 0, z = 0; for (short i = 0; i < s.size(); i++) // Calcula a quantidade total de simbolos z+= s[i].getOcorrence(); for (short i = 0; i < s.size(); i++) s[i].calculateProbability(z); do // Atribui o codigo zero aos simbolos do lado esquerdo da arvore { x += s[i].getProbability(); s[i].addCharCode('0'); i++; w = x + s[i].getProbability(); }while (w < 0.5); // Calcula a diferença de probabilidade das partes da arvore w = abs(0.5 - w); x = abs(0.5 - x); a = abs(w - x); if (!((a < std::numeric_limits<double>::epsilon())&&(a!=0))&&(w < x)) // Neste caso é melhor pegar o proximo elemento // (sua probabilidade fica mais equilibrada com a do outro lado da arvore) { s[i].addCharCode('0'); i++; } j = i; while (i < s.size()) // Atribui o codigo um aos simbolos do lado direito da arvore { s[i].addCharCode('1'); i++; } // Separa o vector de simbolos em duas partes a depender da probabilidade dos mesmos vector<Symbol> newS (s.begin(),s.begin()+j); vector<Symbol> newS1 (s.begin()+j,s.end()); // (s.begin()+j+1 se for no windows) if (j > 1) // Neste caso existem mais do que um elementos do lado esquerdo, logo é necessario expandir ambos os lados da arvore { makeCodes(newS); makeCodes(newS1); } else if (i > 2) // Neste caso existe mais do que dois elementos do lado direito, logo so é necessario expandir o lado direito da arvore makeCodes(newS1); for (int y = 0; y < s.size(); y++) // Atribui o codigo dos simbolos de acordo com a posição dos mesmos na arvore if (y < j) s[y].setCode(newS[y].getCode()); else s[y].setCode(newS1[y-j].getCode()); }