Code Vonc

Compresseur

v 1.0

Win

TéléchargerDownload
Faire un donMake a donation
CommentairesComments

Programme de compression et de décompression de fichiers selon les algorithmes 7 bits et LZ77.

Équipe du projet : César Guillotel, Vivien Piris.





Présentation
Mode d'emploi

Description

Compresse et décompresse des fichiers selon les algorithmes :

- 7 bits
- LZ77

Le fichier compressé 7 bits possède l'extension .7bit
Le fichier compressé LZ77 possède l'extension .lz77
Le fichier décompressé possède le suffixe "_dc".

Utilisation

1. Cliquez sur "Fichier" pour sélectionner un fichier à compresser ou à décompresser.
2. Cliquez sur "LZ77" ou "7 bits" pour changer le mode de compression.
3. a. Cliquez sur "Compresser" pour compresser le fichier sélectionné.
3. b. Ou cliquez sur "Décompresser" pour décompresser le fichier sélectionné.

Compression 7 bits

tc[n] = (t[n] << x) | (t[n + 1] >> y) avec x de 1 à 7 y de 6 à 0

À chaque gain d’octet, passer x à 1, y à 6 et lire un octet plus loin dans le tableau original (t).

Décompression 7 bits

t[n] = (tc[n - 1] << x) | (tc[n] >> y) avec x de 7 à 0 y de 1 à 8

À chaque ajout d’octet, passer x à 7, y à 1 et lire un octet moins loin dans le tableau original (t).

Compression LZ77

On parcourt le tableau (t) dont les 256 caractères avant la case lue constituent le dictionnaire.

• Tant que la suite de cases lues existe dans le dictionnaire, sauvegarder sa position dans le dictionnaire et sa taille.

- Si la suite de case n’existe plus dans le dictionnaire, écrire la position, la taille et la valeur de la dernière case lue.

• Si la case lue n’est pas présente dans le dictionnaire, enregistrer la position 0, longueur 0, et la valeur de la case lue

Décompression LZ77

Parcourir le tableau (t) selon la structure : { position, longueur, valeur } qui constituent chaque élément compressé

Le dictionnaire constitue les 256 dernières valeurs décompressées.

• Pour chaque élément, récupérer les valeurs du dictionnaire à partir de la position et de la longueur de chaque élément.

• Si la longueur est nulle, écrire directement la valeur de l’élément





Codes sourcesSources code

Lisez-moi.txt


   ______                                                         
  / ____/___  ____ ___  ____  ________  _____________  __  _______
 / /   / __ \/ __ `__ \/ __ \/ ___/ _ \/ ___/ ___/ _ \/ / / / ___/
/ /___/ /_/ / / / / / / /_/ / /  /  __(__  |__  )  __/ /_/ / /    
\____/\____/_/ /_/ /_/ .___/_/   \___/____/____/\___/\__,_/_/     
                    /_/                                           

Compresseur v 1.0
Créé par César Guillotel et Vivien Piris.

┌──────────────┐
│ Description  │
└──────────────┘

Compresse et décompresse des fichiers selon les algorithmes :

- 7 bits
- LZ77

Le fichier compressé 7 bits possède l'extension .7bit
Le fichier compressé LZ77 possède l'extension .lz77
Le fichier décompressé possède le suffixe "_dc".


┌──────────────┐
│ Utilisation  │
└──────────────┘

1. Cliquez sur "Fichier" pour sélectionner un fichier à compresser ou à décompresser.
2. Cliquez sur "LZ77" ou "7 bits" pour changer le mode de compression.
3. a. Cliquez sur "Compresser" pour compresser le fichier sélectionné.
3. b. Ou cliquez sur "Décompresser" pour décompresser le fichier sélectionné.


┌──────────────┐
│ Informations │
└──────────────┘

Le programme utilise la bibliothèque SDL.
Le programme est compilé pour Windows.

compressionLZ77.c

#include <stdlib.h>
#include <stdio.h>
#include "compressionLZ77.h"
#include "fonctions.h"


//Double the allocated memory of an array

int increaseArray(char** octets, int* arraySize) {

    if (*octets == NULL) return 0;

    char* array2 = (char*)malloc(sizeof(char) * (*arraySize) * 2);
    if (array2 == NULL) return 0;

    int i;

    for (i = 0 ; i < *arraySize ; i++) {

        array2[i] = (*octets)[i];
    }

    free(*octets);

    *octets = array2;
    *arraySize = (*arraySize) * 2;

    return 1;
}


// Double the allocated memory of an array of elements

int increaseElements(Element** elements, int* arraySize) {

    if (*elements == NULL) return 0;

    *elements = (Element*)realloc(*elements, sizeof(Element) * (*arraySize) * 2);

    *arraySize = (*arraySize) * 2;

    return 1;

    Element* array2 = (Element*)malloc(sizeof(Element) * (*arraySize) * 2);
    if (array2 == NULL) return 0;

    int i;

    for (i = 0 ; i < *arraySize ; i++) {

        array2[i].length = (*elements)[i].length;
        array2[i].start = (*elements)[i].start;
        array2[i].value = (*elements)[i].value;
    }

    free(*elements);

    *elements = array2;
    *arraySize = (*arraySize) * 2;

    return 1;
}

// Send if the byte is in the dictionary or not

int isInDicLZ77(char* dico, int dicoSize, char octet) {

    int i;

    for (i = 0 ; i < dicoSize ; i++) {

        if (dico[i] == octet) {

            return 1;
        }
    }

    return 0;
}


// Send all index in the dictionary which contains the searched Byte

void findAllInDicLZ77(int* allIdsInDico, char* dico, int dicoSize, char octet, int* idsSize) {

    int i;
    *idsSize = 0;

    for (i = 0 ; i < dicoSize ; i++) {

        if (dico[i] == octet) {

            allIdsInDico[*idsSize] = i;
            (*idsSize)++;
        }
    }

}


//remove id's chain which don't correspond

void removeIdsDontCheck(int* allIdsInDico, int* idsSize, char* dico, int dicoSize, int elementsLength, char octet) {

    int i;
    int id;
    int idsSize2 = 0;

    for (i = 0 ; i < *idsSize ; i++) {

        id = allIdsInDico[i];

        if (id + elementsLength < dicoSize && dico[id + elementsLength] == octet) {
            allIdsInDico[idsSize2] = id;
            idsSize2++;
        }
    }

    *idsSize = idsSize2;
}


// Add the Byte to the dictionary

void addToDicLZ77(char* dico, int* dicoSize, char octet, int id) {

    if (*dicoSize == 256) {

        // Shift all the data from the dictionary to the left, to accept the new value in the last box
        int i;
        for (i = 0 ; i < *dicoSize - 1 ; i++) {

            dico[i] = dico[i + 1];
        }

        dico[*dicoSize - 1] = octet;
    }
    else {

        dico[*dicoSize] = octet;

        (*dicoSize)++;
    }

}


// Add an element to an array of element

void addElementLZ77(Element** elements, int* nbElements, int* elementsSize, char octet, char start, int length) {

    if (*nbElements >= *elementsSize) {

        increaseElements(elements, elementsSize);
    }

    while ( length > 255) {

        (*elements)[*nbElements].start = start;
        (*elements)[*nbElements].length = 255;
        (*elements)[*nbElements].value = octet;
        (*nbElements)++;

        length -= 256;

        if (*nbElements >= *elementsSize) {

            increaseElements(elements, elementsSize);
        }
    }

    (*elements)[*nbElements].start = start;
    (*elements)[*nbElements].length = (char)length;
    (*elements)[*nbElements].value = octet;
    (*nbElements)++;

}

/*

0 1 2 3 4 5 6 7 8 9 10
G A T A C C A T T A C A A G T C C A

00G 00A 00T 11C 41A 21T 32A 11G 21C 52

*/

// Created the array of elements, which the final array that will be written to the file

Element* createElementsLZ77(FILE* file, int* nbElements, int* etat) {

    //result of the compression

    int elementsSize = 256;
    Element* elements = (Element*)malloc(sizeof(Element) * elementsSize);

    if (elements == NULL) {
        *etat = COMPRESSION_ERROR;
        return NULL;
    }

    // Dictionnary

    char* dico = (char*)malloc(sizeof(char) * 256);

    if (dico == NULL) {
        *etat = COMPRESSION_ERROR;
        free(elements);
        return NULL;
    }

    //Byte found in the dictionary

    int* allIdsInDico = (int*)malloc(sizeof(int) * 256);

    if (allIdsInDico == NULL) {
        free(elements);
        free(dico);
        *etat = COMPRESSION_ERROR;
        return NULL;
    }

    // Variables

    char octet;
    int dicoSize = 0; // Size of the dictionary
    int elementsLength = 0; // Number of successive dictionary ids for read bytes
    int idsSize = 0; // Number of IDs found in the dictionary for the given byte
    int id = 0; // ID in the dictionary


    while (fread(&octet, 1, 1, file)) {

        int isInDico = isInDicLZ77(dico, dicoSize, octet);

        // if the byte is in he dictionary

        if (isInDico) {

            // If we have no ids of the dictionary currently found

            if (idsSize == 0) {

                // Find the occurrences of the current byte in the dictionary
                // Example :
                //      dico = [A, B, A, C]
                //      octet = A
                //      allIdsInDico = [0, 2]

                findAllInDicLZ77(allIdsInDico, dico, dicoSize, octet, &idsSize);

                elementsLength++;
            }

            else {

                // Removes the sequences of id that do not match it
                // Example :
                //      dico = [A, B, A, C]
                //      octet = C
                //      allIdsInDico = [2]

                char start = allIdsInDico[0];

                removeIdsDontCheck(allIdsInDico, &idsSize, dico, dicoSize, elementsLength, octet);

                // If there are no more indices corresponding to the byte sequence, add the element

                if (idsSize == 0) {

                    addElementLZ77(&elements, nbElements, &elementsSize, octet, start, elementsLength);

                    elementsLength = 0;
                }
                else {
                    elementsLength++;
                }
            }
        }

        // if the byte is not in the dictionary

        else {

            // If we were already in a series of indices, add the element with the index

            if (idsSize) {

                addElementLZ77(&elements, nbElements, &elementsSize, octet, allIdsInDico[0], elementsLength);
            }

            // else add a new element

            else {

                addElementLZ77(&elements, nbElements, &elementsSize, octet, 0, 0);
            }

            idsSize = 0;
            elementsLength = 0;
        }

        addToDicLZ77(dico, &dicoSize, octet, id);

        id++;
    }

    // add the last element

    if (idsSize) {

        addElementLZ77(&elements, nbElements, &elementsSize, 0, allIdsInDico[0], elementsLength);
    }

    free(allIdsInDico);
    free(dico);

    return elements;
}


// create an array of byte which are from the lz77 compression

 char* createOctetsLZ77(FILE* file, int* nbOctets, int* etat) {

    int dicoSize = 256;

    int arraySize = 4;
    char* octets = (char*)malloc(sizeof(char) * arraySize);

    if (octets == NULL) {
        *etat = DECOMPRESSION_ERROR;
        return NULL;
    }

    Element* element = (Element*)malloc(sizeof(Element));

    if (element == NULL) {
        *etat = DECOMPRESSION_ERROR;
        free(octets);
        return NULL;
    }

    *nbOctets = 0;

    int i;
    char octet;
    int dicoDecalage = 0;


    // we retrieve each element

    while (fread(element, sizeof(Element), 1, file)) {


        // For each element, retrieve the characters of the dictionary from the start id and the length of each element
        for (i = 0 ; i < element->length ; i++) {

            dicoDecalage = (*nbOctets - dicoSize); // Offset of the dictionary window
            if (dicoDecalage < 0) dicoDecalage = 0;

            octet = octets[element->start + i + dicoDecalage];

            octets[*nbOctets] = octet;

            (*nbOctets)++;

            if (*nbOctets >= arraySize) {

                if (!increaseArray(&octets, &arraySize)) {

                    // Error of malloc
                    *etat = DECOMPRESSION_ERROR;
                    free(element);
                    free(octets);
                    return NULL;
                }
            }
        }


        // Then adds the character of the element

        octets[*nbOctets] = element->value;

        (*nbOctets)++;

        if (*nbOctets >= arraySize) {

            if (!increaseArray(&octets, &arraySize)) {

                // Error of malloc
                *etat = DECOMPRESSION_ERROR;
                free(element);
                free(octets);
                return NULL;
            }
        }
    }




    //(*nbOctets)--;

    free(element);

    return octets;
}


// write the compress file

void writeFileLZ77(FILE* fileCompressed, Element* dico, int dicoSize) {

    int i;
    Element ele;

    for (i = 0 ; i < dicoSize ; i++) {

        ele = dico[i];

        fwrite(&(ele.start), sizeof(char), 1, fileCompressed);
        fwrite(&(ele.length), sizeof(char), 1, fileCompressed);
        fwrite(&(ele.value), sizeof(char), 1, fileCompressed);
    }
}


// write the original not compress file

void writeFileOriginalLZ77(FILE* fileDecompressed, char* octets, int nbOctets) {

    int i;
    fwrite(octets, sizeof(char), nbOctets, fileDecompressed);

}


// Compress

int compressionLZ77(char* path, Etats* etats) {

    if (etats->fichier != FILE_OK) return COMPRESSION_ERROR;

    FILE *file = NULL;
    FILE *fileCompressed = NULL;
    char pathCompressed[1024];
    int pathSize = strlen(path);

    // File not compress
    file = fopen(path, "rb");
    if (file == NULL) return COMPRESSION_ERROR;

    // File  compress
    strcpy(pathCompressed, path);
    pathCompressed[pathSize] = '.';
    pathCompressed[pathSize+1] = 'l';
    pathCompressed[pathSize+2] = 'z';
    pathCompressed[pathSize+3] = '7';
    pathCompressed[pathSize+4] = '7';
    pathCompressed[pathSize+5] = '\0';
    fileCompressed = fopen(pathCompressed, "wb+");

    if (fileCompressed == NULL) {
        fclose(file);
        return COMPRESSION_ERROR;
    }

    // Compress

    int etat = COMPRESSION_OK;
    int nbElements = 0;
    Element* elements = createElementsLZ77(file, &nbElements, &etat);

    writeFileLZ77(fileCompressed, elements, nbElements);

    if (elements) free(elements);


    // close

    fclose(file);
    fclose(fileCompressed);
    return etat;
}


// Decompress

int decompressionLZ77(char* path, Etats* etats) {

    if (etats->fichier != FILE_OK) return DECOMPRESSION_ERROR;

    FILE *file = NULL;
    FILE *fileDecompressed = NULL;
    char pathDecompressed[1024];
    int pathSize = strlen(path);

    // File compress
    file = fopen(path, "rb");
    if (file == NULL) return DECOMPRESSION_ERROR;

    // File decompress
    strcpy(pathDecompressed, path);
    addStringUncompressed(pathDecompressed, pathSize);
    fileDecompressed = fopen(pathDecompressed, "wb+");

    if (fileDecompressed == NULL) {
        fclose(file);
        return DECOMPRESSION_ERROR;
    }

    // Decompress

    int etat = DECOMPRESSION_OK;
    int nbOctets = 0;
    char* octets = createOctetsLZ77(file, &nbOctets, &etat);

    writeFileOriginalLZ77(fileDecompressed, octets, nbOctets);

    if (octets) free(octets);


    // close

    fclose(file);
    fclose(fileDecompressed);


    return etat;
}

compressionLZ77.h

#ifndef _COMPRESSEUR_Z77_
#define _COMPRESSEUR_Z77_

#include "compressionLZ77.h"
#include "fonctions.h"

//Dictionary Elements

typedef struct element {

    unsigned char start;
    unsigned char length;
    char value;

} Element;

typedef struct dico {

    char octet;
    char id;

} Dico;

int increaseArray(char**, int*);
int increaseElements(Element**, int*);
int isInDicLZ77(char*, int, char);
void findAllInDicLZ77(int*, char*, int, char, int*);
void removeIdsDontCheck(int*, int*, char*, int, int, char);
void addToDicLZ77(char*, int*, char, int);
void addElementLZ77(Element**, int*, int*, char, char, int);
Element* createElementsLZ77(FILE*, int*, int*);
char* createOctetsLZ77(FILE*, int*, int*);
void writeFileLZ77(FILE*, Element*, int);
void writeFileOriginalLZ77(FILE* , char*, int);
int compressionLZ77(char*, Etats*);
int decompressionLZ77(char*, Etats*);
#endif

compressionSevenBit.c

#include "stdio.h"
#include "fonctions.h"
#include "compressionSevenBit.h"
#include <math.h>

//
//This function is used to Compress the file into a string which will be include in a file.
char* createSevenBit(FILE* f, int* sizeFile){

    fseek(f, 0L, SEEK_END);

    int k = ftell(f);


    int nbmax = (k * 7 / 8);
    if ((k * 7) % 8 != 0) nbmax++;
    *sizeFile = nbmax;

    char* s = (char*) malloc(sizeof(char) * k);

    char* s2 =(char*) malloc(sizeof(char) * k);

    fseek(f, 0L, SEEK_SET);
    fread(s, sizeof(char), k, f);

    int g = 1;
    int d = 6;
    int j = 0;

    for (int i = 0 ; i < k ; i++){

        s2[i] = 0;

        if (i + j < k) {
            s2[i] = s[i + j] << g;
        }

        if (i + j + 1 < k) {
             s2[i] |= s[i + j + 1] >> d;
        }

        g += 1;
        d -= 1;

        if (d == -1) {
            g = 1;
            d = 6;
            j += 1;
        }
    }

    free(s);
    s = NULL;

    return s2;
}

// This Function is used to Decompress  the file encoded in seven bit
unsigned char * decompression7Bit(FILE* f, int* sizeFile) {

    fseek(f, 0L, SEEK_END);

    int k = ftell(f);
    unsigned char* s2 =malloc(sizeof(unsigned char)*(k));


    fseek(f, 0L, SEEK_SET);

    int  nbmax = (k * 8 / 7);
    if ((k * 8) % 7 != 0) nbmax++;
    *sizeFile = nbmax;

    unsigned char* t = malloc(sizeof(unsigned char)*(nbmax));
    fread(s2, sizeof(unsigned char), k, f);

    int x = 7;
    int y = 1;
    int j = 0;

    for (int i = 0 ; i < nbmax ; i++) {

        t[i] = 0;

        unsigned char masque = 255;

        if (y != 1){
            masque = (255 << x);
            t[i] |= (s2[i + j - 1] << x) & masque;
        }

        if (x != 0 ){
            masque = (255 >> y);
            t[i] |= (s2[i + j] >> y) & masque;
        }

        unsigned char cvs = 127;
        t[i] &= cvs;

        x -= 1;
        y += 1;

        if (x == -1){
            x = 7;
            y = 1;
            j -= 1;
        }

    }

    free(s2);
    s2 = NULL;
    return t;

}


// this function open the file and  launch the  compression function and write the result in a new file
int compressionToSevenBit(char* path, Etats* etats) {

    if (etats->fichier != FILE_OK) return COMPRESSION_ERROR;

    FILE *file = NULL;
    FILE *fileCompressed = NULL;
    char pathCompressed[1024];
    int pathSize = strlen(path);

    // File cot compressed
    file = fopen(path, "rb");
    if (file == NULL) return COMPRESSION_ERROR;

    // File compressed
    strcpy(pathCompressed, path);
    pathCompressed[pathSize] = '.';
    pathCompressed[pathSize+1] = '7';
    pathCompressed[pathSize+2] = 'b';
    pathCompressed[pathSize+3] = 'i';
    pathCompressed[pathSize+4] = 't';
    pathCompressed[pathSize+5] = '\0';
    fileCompressed = fopen(pathCompressed, "wb+");

    if (fileCompressed == NULL) {
        fclose(file);
        return COMPRESSION_ERROR;
    }

    // Compress

    int sizeFile = 0;
    char* str = createSevenBit(file, &sizeFile);
    fwrite(str, sizeof(char), sizeFile, fileCompressed);

    fclose(file);
    fclose(fileCompressed);

    if (str) free(str);
    str = NULL;

    return COMPRESSION_OK;
}


// this function open the file use the decompression function and write the result in a new file
int decompressionToSevenBit(char* path, Etats* etats) {

    if (etats->fichier != FILE_OK) return DECOMPRESSION_ERROR;

    FILE *file = NULL;
    FILE *fileDecompressed = NULL;
    char pathDecompressed[1024];
    int pathSize = strlen(path);

    // File compressed
    file = fopen(path, "rb");
    if (file == NULL) return DECOMPRESSION_ERROR;

    // File decompressed
    strcpy(pathDecompressed, path);
    addStringUncompressed(pathDecompressed, pathSize);
    fileDecompressed = fopen(pathDecompressed, "wb+");

    if (fileDecompressed == NULL) {
        fclose(file);
        return DECOMPRESSION_ERROR;
    }

    // Decompress

    int etat = DECOMPRESSION_OK;
    int nbOctets = 0;


    int sizeFile = 0;
    unsigned char* str = decompression7Bit(file, &sizeFile);

    fwrite(str, sizeof(unsigned char), sizeFile, fileDecompressed);

    if (str) free(str);
    str = NULL;

    // Close

    fclose(file);
    fclose(fileDecompressed);


    return etat;
}


compressionSevenBit.h

#ifndef COMPRESSIONSEVENBIT_H_INCLUDED
#define COMPRESSIONSEVENBIT_H_INCLUDED

char* createSevenBit(FILE*, int*);
int compressionToSevenBit(char*, Etats*);
int decompressionToSevenBit(char*, Etats*);
unsigned char * decompression7Bit(FILE*, int*);
#endif // COMPRESSIONSEVENBIT_H_INCLUDED

fonctions.c

#include <stdlib.h>
#include <stdio.h>
#include <SDL/SDL.h>
#include <windows.h>
#include "fonctions.h"

// Calls the file selection window
void ouvrir(char* chemin) {
    OPENFILENAME ofn;
    int res;
    chemin[0] = '\0';

    ZeroMemory(&ofn, sizeof(OPENFILENAMEW));
    ofn.lStructSize = sizeof(OPENFILENAMEW);
    ofn.lpstrFile = chemin;
    ofn.nMaxFile = 1024;
    //ofn.Flags = OFN_LONGNAMES | OFN_EXPLORER;

    ofn.lpstrFilter = "Fichier (*.*)\0*.*\0";

    res = GetOpenFileName(&ofn);
    if (!res) chemin[0] = '\0';
}

// Calls the decompression function according to the choice of the user
int decompresser(char* chemin, Etats* etats) {
    if (etats->fichier != FILE_OK) return DECOMPRESSION_ERROR;

    if (etats->typeCompression == TYPECOMPRESSION_LZ77)
        return decompressionLZ77(chemin, etats);

    if (etats->typeCompression == TYPECOMPRESSION_7BTS)
        return decompressionToSevenBit(chemin, etats);

    return DECOMPRESSION_ERROR;
}

// Calls the compression function according to the choice of the user
int compresser(char* chemin, Etats* etats) {
    if (etats->fichier != FILE_OK) return DECOMPRESSION_ERROR;

    if (etats->typeCompression == TYPECOMPRESSION_LZ77)
        return compressionLZ77(chemin, etats);

    if (etats->typeCompression == TYPECOMPRESSION_7BTS)
        return compressionToSevenBit(chemin, etats);

    return COMPRESSION_ERROR;
}

// Checks whether the selected file can be opened
int verifFichier(char* chemin) {
    if (chemin[0] == '\0') return FILE_IDLE;
    FILE *fic = NULL;
    fic = fopen(chemin, "r");
    if (fic == NULL) return FILE_ERROR;
    fclose(fic);
    return FILE_OK;
}

// Mouse click actions based on position
void verifBoutons(SDL_Event event, char* chemin, Etats* etats) {

    if (event.button.button == SDL_BUTTON_LEFT) {

        if (event.button.y < 38 && event.button.x < 183) { // select algo

            if (etats->typeCompression == TYPECOMPRESSION_7BTS) etats->typeCompression = TYPECOMPRESSION_LZ77;
            else if (etats->typeCompression == TYPECOMPRESSION_LZ77) etats->typeCompression = TYPECOMPRESSION_7BTS;
        }
        if (event.button.y < 38 && event.button.x > 183) { // choose file

            ouvrir(chemin);
            etats->fichier = verifFichier(chemin);
            etats->compression = COMPRESSION_IDLE;
            etats->decompression = DECOMPRESSION_IDLE;
        }
        if (event.button.y > 38 && event.button.x < 183) { // Compress

            etats->compression = compresser(chemin, etats);
        }
        if (event.button.y > 38 && event.button.x > 183) { // Decompress

            etats->decompression = decompresser(chemin, etats);
        }
    }
}

// Events SDL
int evenements(char* chemin, Etats* etats) {
    SDL_Event event;
    while (SDL_PollEvent(&event)) {
        switch (event.type) {
            case SDL_QUIT:
                return 0;

            case SDL_KEYDOWN: {
                if (event.key.keysym.sym == SDLK_ESCAPE) return 0; // Touche échap
                break;
            }

            case SDL_MOUSEBUTTONUP : {
                verifBoutons(event, chemin, etats);
                break;
            }
        }
    }
    return 1;
}

// Update of the interface according to the status of the actions
void affichageEtat(SDL_Surface* surface, SDL_Surface* bmp_0, SDL_Surface* bmp_1, int etat, SDL_Rect bmp_pos, int x, int y) {
    bmp_pos.x = x;
    bmp_pos.y = y;
    if (etat == 2) SDL_BlitSurface(bmp_0, 0, surface, &bmp_pos);
    else if (etat == 1) SDL_BlitSurface(bmp_1, 0, surface, &bmp_pos);
}

//Interface Update
void affichage(SDL_Surface* surface, SDL_Surface* bmp, SDL_Surface* bmp_0, SDL_Surface* bmp_1, SDL_Surface* bmp_7bits, SDL_Surface* bmp_lz77, Etats* etats) {
    SDL_Rect bmp_pos;

    bmp_pos.x = bmp_pos.y = 0;
    SDL_BlitSurface(bmp, 0, surface, &bmp_pos);

    //affichageEtat(surface, bmp_0, bmp_1, etats->, bmp_pos, 162, 15);
    affichageEtat(surface, bmp_0, bmp_1, etats->fichier, bmp_pos, 330, 15);
    affichageEtat(surface, bmp_0, bmp_1, etats->compression, bmp_pos, 162, 50);
    affichageEtat(surface, bmp_0, bmp_1, etats->decompression, bmp_pos, 330, 50);


    SDL_Rect bmp_comp_pos;
    bmp_comp_pos.x = 45;
    bmp_comp_pos.y = 0;

    if (etats->typeCompression == TYPECOMPRESSION_7BTS) {

        SDL_BlitSurface(bmp_7bits, 0, surface, &bmp_comp_pos);
    }
    else if (etats->typeCompression == TYPECOMPRESSION_LZ77) {

        SDL_BlitSurface(bmp_lz77, 0, surface, &bmp_comp_pos);
    }

    SDL_Flip(surface);
}


// Add string to uncompressed filename
void addStringUncompressed(char* path, int pathSize) {

    int isLZ77Or7bits = 0;

    if (path[pathSize - 5] == '.' &&
        path[pathSize - 4] == 'l' &&
        path[pathSize - 3] == 'z' &&
        path[pathSize - 2] == '7' &&
        path[pathSize - 1] == '7') {

        isLZ77Or7bits = 1;
    }

    if (path[pathSize - 5] == '.' &&
        path[pathSize - 4] == '7' &&
        path[pathSize - 3] == 'b' &&
        path[pathSize - 2] == 'i' &&
        path[pathSize - 1] == 't') {

        isLZ77Or7bits = 1;
    }

    // Find the last point of the extension, ignoring the .lz77 or .7bit extension if exists

    int iext = pathSize - 1;
    if (isLZ77Or7bits) iext -= 5;

    path[iext + 1] = '\0';

    int ipt = iext;
    int i = iext;

    while (i > 0 && path[i] != '\\' && path[i] != '/') {

        if (path[i] == '.') {

            ipt = i;
            break;
        }

        i--;
    }

    // Insert string before the extension

    char ext[256];
    int j = 0;

    for (i = ipt ; i <= iext+1 ; i++) {

        ext[j++] = path[i];
    }

    j = 0;

    for (i = ipt ; i <= iext+1 ; i++) {

        path[i+3] = ext[j++];
    }

    path[ipt] = '_';
    path[ipt+1] = 'd';
    path[ipt+2] = 'c';

}

fonctions.h

#ifndef _COMPRESSEUR_FONCTIONS_
#define _COMPRESSEUR_FONCTIONS_

#define FILE_IDLE 0
#define FILE_OK 1
#define FILE_ERROR 2
#define COMPRESSION_IDLE 0
#define COMPRESSION_OK 1
#define COMPRESSION_ERROR 2
#define DECOMPRESSION_IDLE 0
#define DECOMPRESSION_OK 1
#define DECOMPRESSION_ERROR 2
#define TYPECOMPRESSION_7BTS 0
#define TYPECOMPRESSION_LZ77 1

#include "fonctions.h"
#include <SDL/SDL.h>

typedef struct etats {

    int fichier;
    int compression;
    int decompression;
    int typeCompression;

} Etats;

void ouvrir(char* chemin);
int decompresser(char* chemin, Etats* etats);
int compresser(char* chemin, Etats* etats);
int verifFichier(char* chemin);
void verifBoutons(SDL_Event event, char* chemin, Etats* etats);
int evenements(char* chemin, Etats* etats);
void affichageEtat(SDL_Surface* surface, SDL_Surface* bmp_0, SDL_Surface* bmp_1, int etat, SDL_Rect bmp_pos, int x, int y);
void affichage(SDL_Surface* surface, SDL_Surface* bmp, SDL_Surface* bmp_0, SDL_Surface* bmp_1, SDL_Surface* bmp_7bits, SDL_Surface* bmp_lz77, Etats* etats);



#endif

main.c

#include <stdlib.h>
#include <stdio.h>
#include <SDL/SDL.h>
#include <windows.h>
#include "fonctions.h"

int main(int argc, char** argv) {

    SDL_Surface *surface;
    SDL_Surface *bmp;
    SDL_Surface *bmp_0;
    SDL_Surface *bmp_1;
    SDL_Surface *bmp_7bits;
    SDL_Surface *bmp_lz77;
    int boucle = 1;
    char chemin[1024]; chemin[0] = '\0';
    Etats etats = {FILE_IDLE, COMPRESSION_IDLE, DECOMPRESSION_IDLE, TYPECOMPRESSION_LZ77};

    if (SDL_Init(SDL_INIT_VIDEO) == -1) return EXIT_FAILURE;

    surface = SDL_SetVideoMode(350, 72, 24, SDL_HWSURFACE);
    if (surface == NULL) return EXIT_FAILURE;

    SDL_WM_SetCaption("Compresseur", NULL);

    bmp = SDL_LoadBMP("interface.bmp");
    bmp_0 = SDL_LoadBMP("0.bmp");
    bmp_1 = SDL_LoadBMP("1.bmp");
    bmp_7bits = SDL_LoadBMP("7bits.bmp");
    bmp_lz77 = SDL_LoadBMP("lz77.bmp");

    if (!bmp || !bmp_0 || !bmp_1 || !bmp_7bits || !bmp_lz77) return EXIT_FAILURE;

    while (boucle) {
        boucle = evenements(chemin, &etats);
        affichage(surface, bmp, bmp_0, bmp_1, bmp_7bits, bmp_lz77, &etats);
    }

    SDL_Quit();
    return EXIT_SUCCESS;

}