Partage
  • Partager sur Facebook
  • Partager sur Twitter

Lecture d'un fichier

Valeurs totalement bizarres...

Sujet résolu
Anonyme
    28 mai 2007 à 14:24:25

    EDIT:ce problème découle en fait d'un autre problème, j'ai donc refait un nouveau post, merci de ne aps poster dans celui-ci

    Bonjour à tous :)

    Un post récent parlant de la création d'une fonction permettant de lire des .gif animés et de les convertir en SDL_Surface, je me suis lancé là-dedans.

    Plutôt que de décoder moi-même chaque image GIF, j'ai décidé de contourner la difficulté en créant, pour chaque image, un fichier intermédiaire et à peu près valide (on verra ça plus tard :-° ), que je fais décoder par IMG_Load().
    Mon problème se situe au niveau de la lecture d'un fichier .gif tout simple, je ne sais pourquoi, mais à partir d'un certain octet (le 898e ici o_O ) il me met tout le temps la même valeur : 0xE8 ... et je ne sais pas pourquoi.
    En ouvrant le fichier avec un éditeur hexa-décimal, je me suis bien rendu compte que ce n'était pas les bonnes valeurs ensuite...

    J'en appelle donc à votre aide. Voici mon code (ne faites gaffes ni à la structure, ni rien, ce sont surtout des tests :-° ) :

    main.cpp (pour l'instant, ça ne fait rien d'autre que d'appeler la fonction en question...)
    #include <SDL/SDL.h>
    #include "GIF.h"

    int main(int argc, char *argv[])
    {
        SDL_Surface** gif;
        int nbImages;

        gif = lireGif("Balle.gif", nbImages);

        if(gif == NULL)
            return 1;

        SDL_Init(SDL_INIT_VIDEO);
        SDL_WM_SetCaption("Mon premier programme SDL !",NULL);
        SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE|SDL_DOUBLEBUF);

        bool continuer = true;
        SDL_Event event;

        while (continuer)
        {
            SDL_WaitEvent(&event);
            switch(event.type)
            {
                case SDL_QUIT:
                    continuer = false;
            }
        }

        SDL_Quit();

        for(int i=0;i<nbImages;i++)
            SDL_FreeSurface(gif[i]);

        delete[] gif;

        return 0;
    }


    GIF.h
    #ifndef DEF_GIF
    #define DEF_GIF

    #include <SDL/SDL.h>
    #include <SDL/SDL_image.h>
    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <string>

    SDL_Surface** lireGif(std::string fileName, int& nbImages);

    #endif


    GIF.cpp
    #include "GIF.h"

    SDL_Surface** lireGif(std::string fileName, int& nbImages)
    {
        nbImages = 0;
        std::vector<SDL_Surface*> gif;
        unsigned char* fichier = NULL;
        unsigned char* cFichier = NULL;
        char c;
        int taille;
        std::fstream file;
        std::string entete, reste;

        /*Ouverture du fichier */
        file.open(fileName.c_str(), std::ios::in);
        if(file.bad())
            return NULL;

        /* Taille du fichier */
        file.seekg(0,std::ios_base::end);
        taille = file.tellg();
        file.seekg(0,std::ios_base::beg);

        fichier = new unsigned char[taille];
        cFichier = fichier;

        /* On recopie le fichier */
        for(int i=0;i<taille;i++)
        {
            file.get(c);
            fichier[i] = c;
        }
        file.close();

        fichier[taille] = 0;

        /* Verification de l'entete */
        if(!(fichier[0]=='G' && fichier[1]=='I' && fichier[2]=='F' &&
            fichier[3]=='8' && fichier[4]=='9' && fichier[5]=='a'))
        {
            delete[] fichier;
            return NULL;
        }

        /* On recopie l'entete */
        while(*cFichier != 0x2C)
        {
            entete += (char)(*cFichier);
            cFichier++;
        }

        while(cFichier != fichier+taille)
        {
    std::cout << "offset" << (int)(cFichier-fichier) << " " << (int)*cFichier << " " << (int)cFichier[1] << std::endl;

            reste += (char)(*cFichier);
            if(*cFichier == (unsigned char)0x00 &&
            (cFichier[1] == (unsigned char)0xEB ||
            cFichier[1] == (unsigned char)0x2C))
            {
                /* Pour les tests, je passe ce morceau... */
                #if 0
                reste += (char)0x3B;
                nbImages++;

                std::ofstream temp;
                temp.open("temp.gif", std::ios::out|std::ios::trunc);


                temp << entete << reste;

                temp.close();
                reste.clear();
                #endif
            }

            cFichier++;
        }

        /* --- FIN LECTURE --- */

        delete[] fichier;

        SDL_Surface** gif_s = (SDL_Surface**)new SDL_Surface*[nbImages];
        for(int i=nbImages-1;i>=0;i--)
        {
            gif_s[i] = gif.back();
            gif.pop_back();
        }

        return gif_s;
    }


    Enfin, pour faire les mêmes tests que moi, voici le .gif à 2 images que j'utilise :

    Image utilisateur

    J'obtiens donc une sortie dans le fichier stdout.txt, mais qui ne correspond pas à mes attentes (je vous passe les 1ers octets..:

    Citation : stdout.txt

    octet890 163 53
    octet891 53 63
    octet892 63 69
    octet893 69 246
    octet894 246 228
    octet895 228 249
    octet896 249 179
    octet897 179 232
    octet898 232 232
    octet899 232 232
    octet900 232 232
    octet901 232 232
    octet902 232 232
    octet903 232 232
    octet904 232 232
    octet905 232 232
    octet906 232 232
    octet907 232 232
    octet908 232 232
    octet909 232 232
    octet910 232 232



    et ça continue comme ça jusqu'à la dernière ligne...


    Voilà, bonne chance et bon courage à ceux qui voudront bien s'intéresser à ce problème, et quoi qu'il en soit, MERCI beaucoup à qui aura la patience nécessaire :)

    EDIT: après quelques test, il s'avère que c'est le fichier qui est mal lu par fstream o_O Je vais essayer avec la méthode C pour voir...

    EDIT² : apparamment, la valeur 0xE8 lui pose vraiment problème, car en le codant façon C, avec une simple boucle while, je n'arrive pas à déterminer la taille correcte. Il s'arrête à l'octet contenant 0xE8 avec ce code:
        while(fgetc(file) != EOF)
            taille++;

    Je ne comprends plus rien... Hilf mir !

    EDIT3 : je poursuis mes tests et il se trouve qu'en fait, ce n'est pas cet octet qui pose problème, mais le suivant (899e ==> 0x1A) qui, lors de sa lecture, fait renvoyer à fgetc() la valeur EOF o_O ...

    EDIT 4 : quelques recherches plus tard, je découvre que ce caractère est appelé caractère SUB et j'ai trouvé quelqu'un qui a déjà eu le même problème d'interruption de la lecture du fichier....mais qui n'a pas reçu de réponse.
    Je vais faire un 2e post pour recentrer le problème sur ce caractère...
    • Partager sur Facebook
    • Partager sur Twitter

    Lecture d'un fichier

    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
    • Editeur
    • Markdown