/** * \fn void findNeedleInSublist(char *needle, sublistPointers *listpt, int *elements, const int size) * \brief Funkcja szukająca na liście typu Sublist, fragmentów łańcucha (needle) w łańcuchu będącym zawartością pola data. * \param needle wskaźnik na łańcuch znaków (część wiekszego łańcucha), którego poszukujemy w innych łańcuchach * \param listpt wskaźnik na strukture przechowującą wskaźniki na początek i koniec listy typu Sublist * \param elements wskaźnik na tablicę w której zapisujemy indeksy znalezionych elementów * \param size ilość elementów tablicy elements */ void findNeedleInSublist(char *needle, sublistPointers *listpt, int *elements, const int size) { Sublist *q = listpt->head; int i = 0; while(q) { if(strstr(q->data, needle)) { if(!isInTab(elements, q->id, size)){ elements[i] = q->id; ++i; } } q = q->next; } }
void huffman(FILE** file, FILE** ptFileOutput, char* fileInputName) { char c; int i = 0; int positionChar = 0; int tailleTab = 0; int tailleCode = 0; int currentChar = 0; float longueurTotaleCode = 0; char* tabChar; char* fileOutputName; int* intTab; char* charTab; char* bufferCode; char charTemp[7]; elementListe* elemL = NULL; elementListe** ptListe = &elemL; /* temps de traitement */ clock_t start_time, end_time; start_time = clock(); intTab = calloc(1, sizeof(int)); charTab = calloc(1, sizeof(char)); if ((intTab == NULL) || (charTab == NULL)) { printf("Erreur d'allocation intTab ou charTab.\n"); exit(-1); } /* parcours du fichier source et remplissage des tableaux de frequence*/ while ((c = fgetc(*file)) != EOF) { /*printf("%c", c);*/ if (isInTab(c, charTab) == -1) { intTab = realloc(intTab, sizeof(int) * tailleTab + 1); charTab = realloc(charTab, sizeof(char) * tailleTab + 1); if ((intTab == NULL) || (charTab == NULL)) { printf("Erreur REALLOC intTab ou charTab.\n"); exit(-1); } intTab[tailleTab] = 1; charTab[tailleTab] = c; tailleTab++; } else { positionChar = isInTab(c, charTab); intTab[positionChar]++; } } /* Affichage tableau */ /*for (i = 0; i < tailleTab; i++) { printf("1-%c %d\n", charTab[i], intTab[i]); }*/ tri(charTab, intTab, tailleTab); /* Affichage tableaux triés */ /*for (i = 0; i < tailleTab; i++) { printf("2-%c %d\n", charTab[i], intTab[i]); }*/ for (i = 0; i < tailleTab; i++) { createChainedList(ptListe, charTab[i], intTab[i]); } /* Affichage liste chainee triée*/ /*for (a = *ptListe;a->suivant!=NULL;a = a->suivant) { printf("3-%c %d\n", a->caractere, a->frequence); }*/ printf("\n"); while ((*ptListe)->suivant != NULL) { insertNewNodeInChainedList(ptListe); } /* La liste ne contient plus qu'un seul element qui contiend l'arbre entier */ tabChar = calloc(1, sizeof(char*)); if (tabChar == NULL) { printf("Erreur d'allocation tabChar.\n"); exit(-1); } /* Parcours d'arbre*/ prefixeHuffmanTree(elemL->noeudIntermediaire, tabChar, 0); /* affichage caractères codés */ for (i = 0; i < 256; i++) { if (code[i]) { printf("'%c': %s\n", i, code[i]); longueurTotaleCode += strlen(code[i]); } } printf("Longueur moyenne d'un symbole : %.2f bits\n", longueurTotaleCode / tailleTab); printf("Compression en cours, veuillez patienter . . .\n"); /*Ecriture de la taille de la table des fréquences */ fileOutputName = calloc((8 + strlen(fileInputName)), sizeof(char)); if (fileOutputName == NULL) { printf("Erreur d'allocation fileOutputName.\n"); exit(-1); } fileOutputName = createBinaryFile(fileInputName, ptFileOutput, ".huffman"); openFile(fileOutputName, ptFileOutput, "wb"); /*ECRITURE DANS LE FICHIER CIBLE*/ /*------------------------------------------------------------*/ /* on écrit la taille du dictionnaire */ fwrite(&tailleTab, sizeof(int), 1, *ptFileOutput); /* Ecriture du dictionnaire de donnees */ for (i = 0; i < tailleTab; i++) { fwrite(&charTab[i], sizeof(char), 1, *ptFileOutput); tailleFileOutput++; fwrite(&intTab[i], sizeof(int), 1, *ptFileOutput); tailleFileOutput += 4; } /*------------------------------------------------------------*/ bufferCode = calloc(1, sizeof(char)); if (bufferCode == NULL) { printf("Erreur d'allocation bufferCode.\n"); exit(-1); } /*pointeur sur le fichier initial pour un nouveau parcours (creation du code)*/ fseek(*file, 0, SEEK_SET); while ((c = fgetc(*file)) != EOF) { tailleFileInput++; for (i = 0; i < 256; i++) { if (c == (char) i) { tailleCode = strlen(code[i]) + strlen(bufferCode) + 1; bufferCode = realloc(bufferCode, tailleCode * sizeof(char)); if (bufferCode == NULL) { printf("Erreur reallocation bufferCode.\n"); } strcat(bufferCode, code[i]); } } } printf("\n"); /* Affichage du buffer */ /*printf("%s\n", bufferCode);*/ tailleCode = strlen(bufferCode); int nboctet = tailleCode / 7; tailleFileOutput += nboctet; for (i = 0; i < nboctet; i++) { strncpy(charTemp, bufferCode, 7); currentChar = binaryToDecimal(charTemp); fwrite(¤tChar, 1, 1, *ptFileOutput); bufferCode += 7; } i = nboctet * 7; /* si il reste des octets */ if (i != tailleCode) { tailleFileOutput++; strcpy(charTemp, bufferCode); if (strlen(charTemp) != 7) { for (i = 0; i < 7; i++) { if (charTemp[i] == '\0') { charTemp[i + 1] = '\0'; charTemp[i] = '0'; } } currentChar = binaryToDecimal(charTemp); fwrite(¤tChar, 1, 1, *ptFileOutput); } } closeFile(ptFileOutput); printf("Taux de compression : %.2llu %% \n", 100 -((tailleFileOutput) * 100 / tailleFileInput)); freeHuffmanTree(elemL->noeudIntermediaire); free(elemL); free(intTab); intTab = NULL; free(charTab); charTab = NULL; free(fileOutputName); fileOutputName = NULL; free(tabChar); tabChar = NULL; end_time = clock(); printf("Compression effectuee en %lu s.", (long) ((end_time - start_time) / CLOCKS_PER_SEC)); }