/**
    * \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;
    }
}
Beispiel #2
0
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(&currentChar, 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(&currentChar, 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));
}