Mon programme marche mais je ne sais pas pourquoi ???

Fermé
GreeFoss - Modifié le 22 oct. 2022 à 16:08
Dalfab Messages postés 706 Date d'inscription dimanche 7 février 2016 Statut Membre Dernière intervention 2 novembre 2023 - 22 oct. 2022 à 18:55

Bonjour,

J'ai créé un programme permettant d'inverser les couleurs d'une image.

Le programme marche très bien, mais le problème viens du fait que je ne comprends pas pourquoi.

Le coupable: fseek(fichier, 0 , SEEK_CUR); qui est situé dans la boucle imbriquée (d'après mes tests, sa position dans celle-ci ne semble pas déranger le programme mais il faut qu'elle reste dans la boucle largeur sinon le programme de marche plus)

Cette ligne, qui n'est pas sensée faire quoi que ce soit, est pourtant celle qui fait marcher mon code et je ne comprends pas pourquoi.

Le code en question : 

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    FILE* fichier = NULL; //initialisation du pointeur fichier
    fichier = fopen("C:\\Users\\Gamer\\Desktop\\Code_Blocks\\test_sae\\test4.bmp", "r+b"); //ouverture du fichier

    unsigned char header[54]; //creation d'un tableau header pour receuillir les information du header de l'image
    fread(header, sizeof(unsigned char), 54, fichier); //remplissage du tableau header

    int largeur = header[0x13]*(16*16)+header[0x12]; //récupération de la largeur depuis le header (la formule est nécéssaire pour le convertir en décimal)

    int hauteur = header[0x17]*(16*16)+header[0x16]; //récupération de la hauteur depuis le header (la formule est nécéssaire pour le convertir en décimal)

    int offset_l = 0;

    if (largeur%4 != 0) //calcul de l'offset pour la largeur s'ajoute a la fin de chaque ligne pour eviter les decalages
    {
        offset_l = (largeur%4);
    }

    unsigned char pixel[3]; //tableau qui va contenir les données pour un pixel

    if (fichier != NULL)
    {
        printf("lecture du fichier confirmée\n"); //validation si le fichier à bien été reconnu

        for (int i = 0; i < hauteur; i++) //on fait une double boucle pour parcourrir l'image en fonction de sa hauteur et sa largeur
        {
            for (int j = 0; j < largeur; j++)
            {
                //printf("1 : %d \n",ftell(fichier)); dit la position dans le fichier pour debuguer

                fread(pixel, sizeof(unsigned char), 3, fichier); //obtient les informations du pixel actuel

                /*INVERSION DES COULEURS*/

                pixel[0] = 255 - pixel[0]; //valeur bleu du pixel
                pixel[1] = 255 - pixel[1]; //valeur vert du pixel
                pixel[2] = 255 - pixel[2]; //valeur rouge du pixel

                /*----------------------*/

                //printf("r : %d | v : %d | b : %d \n",pixel[2],pixel[1],pixel[0]); //pour afficher les données des pixels si besoin

                fseek(fichier, -3 , SEEK_CUR); //on se replace en arrière dans le fichier pour pouvoir éditer les valeurs dans le fichier

                fwrite(pixel, sizeof(unsigned char), 3, fichier); //on remplace les valeurs du pixel

                fseek(fichier, 0 , SEEK_CUR); //TRES IMPORTANT SINON MARCHE PAS JSP PK

                //printf("2 : %d \n",ftell(fichier)); dit la position dans le fichier pour debuguer
            }
            fseek(fichier, offset_l , SEEK_CUR); //on rajoute l'offset après chaque ligne si besoin
        }
    }
    printf("final : %d \n",ftell(fichier)); //renvoie la position finale dans le fichier

    fclose(fichier); //on ferme le fichier utilisé
    return 0;
}

Lorsque cette ligne précise est présente, le programme marche parfaitement

Mais quand on l'enlève, l'image deviens composée uniquement de lignes, chaque pixel sur une ligne ont la même couleur (qui est a peu près la couleur de l'image inversée)

Si quelqu'un saurait m'expliquer pourquoi cette ligne fait fonctionner le programme ça m'aiderait beaucoup.

Merci d'avance!

1 réponse

Dalfab Messages postés 706 Date d'inscription dimanche 7 février 2016 Statut Membre Dernière intervention 2 novembre 2023 101
22 oct. 2022 à 18:55

Bonjour,

Je n'ai pas l'habitude d'utiliser le mode "r+". Je pense que le driver gère un pointeur d'écriture et un pointeur de lecture avec un buffer de lecture et un de lecture. Faire un fseek(fichier, 0 , SEEK_CUR); doit forcer une resynchronisation des 2. Je n'ai pas d'explication précise pour ce cas.

1