Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

DevIL Discussion :

Probleme à l'exécution avec DevIL


Sujet :

DevIL

  1. #1
    Nouveau membre du Club
    Probleme à l'exécution avec DevIL
    Bonjour,
    j'ai un souci en utilisant la libraire DevIL (ou OpenIL) sous C++ pour charger / enregistrer des fichiers images dans / depuis ma classe Image. Le code s'exécute pourtant correctement, un jpeg est lu puis réécrit dans un autre fichier correctement. J'ai pourtant un seg-fault lorsque l'exécution des fonctions de chargement et d'enregistrement est achevée, au moment de rendre la main à la fonction appelante.

    Voici le code des fonctions incriminées :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
     
    Image::Image(const string& fichier, bool p)
    {
       lireFichier(fichier);
       cout << "[Image] yeah !" << endl;
       if(p) initZ();
    }
     
    int Image::lireFichier(const string& fichier)
    {
       cout << "Lecture du fichier " << fichier << "... ";
     
       ILuint imageName;
       ilGenImages(1, &imageName);
       ilBindImage(imageName);
       ilLoadImage(str2char(fichier));
       largeur = (int)ilGetInteger(IL_IMAGE_WIDTH);
       hauteur = (int)ilGetInteger(IL_IMAGE_HEIGHT);
       initRGB();
     
       ILubyte *buffer = new ILubyte[largeur*hauteur*3];
       ilCopyPixels(0, 0, 0, largeur, hauteur, 1, IL_RGB, IL_UNSIGNED_BYTE, buffer);
       int id=0;
       for(int i=0 ; i<hauteur ; i++)
          for(int j=0 ; j<largeur ; j++)
          {
             R[j][i] = (unsigned char)buffer[id++];
             G[j][i] = (unsigned char)buffer[id++];
             B[j][i] = (unsigned char)buffer[id++];
          }
     
       delete[] buffer;
       ilDeleteImages(1, &imageName);
     
       ILenum err = ilGetError();
       if(err != IL_NO_ERROR)
       {
          cout << "Erreur. [" << iluErrorString(err) << "]" << endl;
          return 0;
       }
     
       cout << "OK." << endl;
       //ecrireFichier("img_test.jpg");
       return 1;
    }
     
     
    int Image::ecrireFichier(const string& fichier)
    {
       cout << "Ecriture du fichier " << fichier << "... ";
       ILubyte *buffer = new ILubyte[largeur*hauteur*3];
       int id=0;
       for(int i=hauteur-1 ; i>=0 ; i--)
          for(int j=0 ; j<largeur ; j++)
          {
             buffer[id++] = (ILubyte)R[j][i];
             buffer[id++] = (ILubyte)G[j][i];
             buffer[id++] = (ILubyte)B[j][i];
          }
       ILuint imageName;
       ilGenImages(1, &imageName);
       ilBindImage(imageName);
     
       ilTexImage(largeur, hauteur, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, buffer);
     
       ilEnable(IL_FILE_OVERWRITE);
       ilSaveImage(str2char(fichier));
     
       ilDeleteImages(1, &imageName);
       delete[] buffer;
     
       ILenum err = ilGetError();
       if(err != IL_NO_ERROR)
       {
          cout << "Erreur. [" << iluErrorString(err) << "]" << endl;
          return 0;
       }
     
       cout << "OK." << endl;
       return 1;
    }


    Et la fonction appelante :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int main (int argc, char **argv)
    {
       ilInit();
       iluInit();
       Image *img_test = new Image("photo_jpg.jpg");
       cout << "[main] Yeah ! 1" << endl;
       //img_test->ecrireFichier("img_test.jpg");
       //cout << "[main] Yeah ! 2" << endl;
       delete img_test;
     
       system("PAUSE");
       return EXIT_SUCCESS;
    }


    Le "OK." à la fin des fonctions s'affiche correctement, et ça plante sans avoir écrit le "Yeah" du main.
    Je n'ai pas la moindre idée du souci, à l'aide !

  2. #2
    Rédacteur

    Tu devrais utiliser un debugger, ils sont fait pour ça. Au moins pour localiser un peu plus précisément l'erreur.

    Tu devrais aussi vérifier chaque retour de fonction, et pas seulement une éventuelle erreur à la fin de la fonction.

  3. #3
    Expert éminent sénior
    Penses aussi à bien vérifier que tu ne fais pas de débordement mémoire...

    Voici les doutes que j'ai vu que je n'ai pas tout le code sous la main :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
       if(p) initZ();

    Que fait la fonction initZ? que vaut p?

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
       initRGB();
    Que fait cette fonction?

    ILubyte *buffer = new ILubyte[largeur*hauteur*3];

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    R[j][i] = (unsigned char)buffer[id++];
    G[j][i] = (unsigned char)buffer[id++];
    B[j][i] = (unsigned char)buffer[id++];
    Déjà, comment ont été alloué ces tableaux? De plus, ce n'est pas une
    bonne idée de mettre un incrémenteur dans une instruction de ce genre
    préférer:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    R[j][i] = (unsigned char)buffer[id];
    id++;
    G[j][i] = (unsigned char)buffer[id];
    id++;
    B[j][i] = (unsigned char)buffer[id];
    id++;

    Ensuite, tu as mis ta largeur comme première dimension? Est-ce que
    l'allocation en a tenu rigueur?


    Code :Sélectionner tout -Visualiser dans une fenêtre à part
       ilDeleteImages(1, &imageName);
    Est-ce normal d'effacer l'image, tu ne t'en sers plus après?


    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
             buffer[id++] = (ILubyte)R[j][i];
             buffer[id++] = (ILubyte)G[j][i];
             buffer[id++] = (ILubyte)B[j][i];


    Même remarque pour les incrémenteurs...

    Jc

    PS: Je pencherais sur un problème avec les tableaux R,G,B...
    Regarde avec un debugger...

  4. #4
    Nouveau membre du Club
    Alors voici plus de détail concernant les allocations mémoire. Le initZ, sert à initialiser un éventuel Z-Buffer au cas où l'image serait du 2,5D.
    A priori il n'y a plus de problème avec ces allocations, vu que dans un premier temps un seg-fault intervenait lors de la tentative d'acces aux tableaux R, G & B et que cela est désormais corrigé. Maintenant le seg-fault intervient après l'exécution de la fonction, alors que l'image est correctement chargée ou écrite ; j'arrive à créer un fichier 'img_test.jpg' identique au 'photo_jpg.jpg' initial, ça bugge juste après.
    Aucun changement en incrémentant le 'id' à part.

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
    void Image::initRGB()
    {
       R = new unsigned char*[largeur];
       G = new unsigned char*[largeur];
       B = new unsigned char*[largeur];
     
       for(int i=0 ; i<largeur ; i++)
       {
          R[i] = new unsigned char[hauteur];
          G[i] = new unsigned char[hauteur];
          B[i] = new unsigned char[hauteur];
     
          for(int j=0 ; j<hauteur ; j++)
          {
          R[i][j] = 0;
          G[i][j] = 0;
          B[i][j] = 0;
          }
       }
    }
     
    void Image::initZ()
    {
       Z = new double*[largeur];
       for(int i=0 ; i<largeur ; i++)
       {
          Z[i] = new double[hauteur];
          for(int j=0 ; j<hauteur ; j++)
          {
          Z[i][j] = 0.;
          }
       }
       profondeur = true;
    }

  5. #5
    Rédacteur

    Tu utilises quoi comme environnement de programmation ? Sur quel système ?

  6. #6
    Nouveau membre du Club
    J'utilise Dev-C++ 4.9.9.2 sous Windows XP Professionnel et la bibliothèque DevIL 1.6.7

  7. #7
    Rédacteur

    Ok, il n'y a donc qu'un bouton à cliquer pour lancer le debugging et trouver l'endroit exact du crash...

  8. #8
    Nouveau membre du Club
    Bon alors maintenant mon souci, je n'ai jamais utilisé et ne sais pas me servir d'un debugger...
    Quand je lance mon programme via le bouton du debugger sous Dev-C++, maintenant il me sort "Erreur. [could not open file]" à propos du 'photo_jpg.jpg', alors qu'il arrivait bien à la charger en exécution normale.

    Je commence à être dépassé par les événements, je ne sais plus quoi faire ! Alors que tout ce que je souhaite (la seule chose manquante pour finaliser mon projet) est tout bêtement de lire et écrire des fichiers images avec ma classe Image !

  9. #9
    Rédacteur

    Bon alors maintenant mon souci, je n'ai jamais utilisé et ne sais pas me servir d'un debugger...
    Le temps que tu vas passer à apprendre les rudiments du debugging te sera bien plus profitable que les centaines de messages que tu aurais posté ici, et pour lesquels on t'aurait trouvé le bug tout cuit

    Quand je lance mon programme via le bouton du debugger sous Dev-C++, maintenant il me sort "Erreur. [could not open file]" à propos du 'photo_jpg.jpg', alors qu'il arrivait bien à la charger en exécution normale.
    Certainement une histoire de chemin relatif. Genre lorsque tu lances le debugging, le répertoire de travail n'est pas le même, et du coup il ne trouve plus les fichiers ayant un chemin relatif. Essaie en spécifiant le chemin complet de tes fichiers dans le programme.

  10. #10
    Nouveau membre du Club
    Oui, faut voir positif, ça me fait l'occasion d'apprendre à me servir du debugger !

###raw>template_hook.ano_emploi###