Ouverture de fichier image incorrecte

Ouverture de fichier image incorrecte - C - Programmation

Marsh Posté le 12-12-2004 à 22:04:56    

Salut à tous !
J'ai un problème avec un programme C, je dois ouvrir un fichier image au format ppm ( du bmp avec une entête ).
Le problème est que ce fichier étant en binaire, les couleurs sont représentées par un caractère entre 0 et 255, or la lecture d'un "0" fait arrêter la lecture du fichier image, vu que c'est en fait '\0'.
Quelqu'un a une idée pour parvenir à lire tout de même le fichier image jusqu'à la fin ?

Reply

Marsh Posté le 12-12-2004 à 22:04:56   

Reply

Marsh Posté le 12-12-2004 à 22:38:10    

Chandy a écrit :

Salut à tous !
J'ai un problème avec un programme C, je dois ouvrir un fichier image au format ppm ( du bmp avec une entête ).
Le problème est que ce fichier étant en binaire, les couleurs sont représentées par un caractère entre 0 et 255, or la lecture d'un "0" fait arrêter la lecture du fichier image, vu que c'est en fait '\0'.
Quelqu'un a une idée pour parvenir à lire tout de même le fichier image jusqu'à la fin ?


 
Le caractère '\0' est utilisée comme valeur spéciale dans les chaînes de caractères pour signifier "fin de chaîne".
Cette valeur est une "convention" ce qui veut dire que les fonctions de manipulations de chaînes cherchent cette valeur lorsqu'elles balayent les chaînes.
 
Les fonctions de lecture de fichier (fread, fgetc, fgets, fscanf) ne sont pas des fonctions de manipulation de chaîne. Elles ne font pas attention au caractère '\0' quand elles le chopent.
 
Le seul soucis qui puisse arriver quand tu manipule un fichier binaire dans le monde "windows" c'est que tu aies oublié de spécifier, dans ta fonction "fopen", d'ouvrir le fichier en mode "binaire".
Au lieu de faire un fopen(fichier, "r" ) faut écrire fopen(fichier, "rb" ). Sinon ton fichier est considéré comme un fichier texte.


Message édité par Sve@r le 13-12-2004 à 11:17:39
Reply

Marsh Posté le 13-12-2004 à 10:08:56    

Chandy a écrit :

Le problème est que ce fichier étant en binaire, les couleurs sont représentées par un caractère entre 0 et 255, or la lecture d'un "0" fait arrêter la lecture du fichier <...>


A part que l'ouverture doit être faite en mode binaire ("rb" ), je ne vois pas ce qui pourrait emp^écher la lecture jusqu'au bout. Montre ton code.


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 13-12-2004 à 10:42:28    

Tu serais pas en train de bloquer la lecture à l'arrivée d'un octet 0 au lieu de tester EOF ?

Reply

Marsh Posté le 13-12-2004 à 11:53:37    

Emmanuel Delahaye a écrit :

A part que l'ouverture doit être faite en mode binaire ("rb" ), je ne vois pas ce qui pourrait emp^écher la lecture jusqu'au bout. Montre ton code.


 
 
Voilà le code brut
 

Citation :

typedef struct {
    int sizeX, sizeY;
    GLubyte *data;
} PPMImage;
 
static PPMImage *LoadPPM(const char *filename)
{
    char buff[16];
    PPMImage *result;
    FILE *fp;
    int maxval,lig_comm=0;
 
    fp = fopen(filename, "rb" );
    if (!fp)
    {
 fprintf(stderr, "Unable to open file `%s'\n", filename);
 exit(1);
    }
 
    if (fread(buff, 1, 3, fp)!=3)
    {
 perror(filename);
 exit(1);
    }
 
    if (buff[0] != 'P' || buff[1] != '6')
    {
 fprintf(stderr, "Invalid image format (must be `P6')\n" );
 exit(1);
    }
 
    if (buff[2] != 0x0a)
      fseek(fp,-1,SEEK_CUR);
 
    while (fgetc(fp) == '#'){
      lig_comm++;
      while (fgetc(fp) != '\n')
 ;
      }
 
    fseek(fp,-1,SEEK_CUR);
 
    result = (PPMImage *)malloc(sizeof(PPMImage));
    if (!result)
    {
 fprintf(stderr, "Unable to allocate memory\n" );
 exit(1);
    }
 
    if (fscanf(fp, "%d %d", &result->sizeX, &result->sizeY) != 2)
    {
 fprintf(stderr, "Error loading image `%s'\n", filename);
 exit(1);
    }
 
    if (fscanf(fp, "%d", &maxval) != 1)
    {
 fprintf(stderr, "Error loading image `%s'\n", filename);
 exit(1);
    }
 
    while (fgetc(fp) != '\n')
 ;
 
    result->data = (GLubyte *)malloc(3 * result->sizeX * result->sizeY);
    if (!result)
    {
 fprintf(stderr, "Unable to allocate memory\n" );
 exit(1);
    }
 
    if (fread(result->data, 3 * result->sizeX, result->sizeY, fp) != result->sizeY)
    {
 fprintf(stderr, "Error loading image `%s'\n", filename);
 exit(1);
    }
 
    fclose(fp);
 
    return result;
}

Et l'image que je charge commence avec une série de points complètement noirs ( 0 donc ), et le pointeur data pointe sur une zone de taille 0, alors que quand je charge une image sans valeur '0', c'est correctement rempli.
Merci pour toutes vos réponses
a++

Reply

Marsh Posté le 13-12-2004 à 12:13:25    

Chandy a écrit :

Voilà le code brut
<snip>


Tu l'aurais en 'compilable', ou il faut que je me tape un demi-heure de rétroingéniérie?

Compiling MAIN.C:
Error MAIN.C 4: Type name expected
Error MAIN.C 4: Declaration missing ;
Error MAIN.C 12: Undefined symbol 'FILE'
Error MAIN.C 12: Undefined symbol 'fp'
Error MAIN.C 13: Declaration is not allowed here
Warning MAIN.C 15: Call to function 'fopen' with no prototype
Error MAIN.C 18: Undefined symbol 'stderr'
Warning MAIN.C 18: Call to function 'fprintf' with no prototype
Warning MAIN.C 19: Call to function 'exit' with no prototype
Warning MAIN.C 22: Call to function 'fread' with no prototype
Warning MAIN.C 24: Call to function 'perror' with no prototype
Warning MAIN.C 25: Call to function 'exit' with no prototype
Warning MAIN.C 30: Call to function 'fprintf' with no prototype
Warning MAIN.C 31: Call to function 'exit' with no prototype
Error MAIN.C 35: Undefined symbol 'SEEK_CUR'
Warning MAIN.C 35: Call to function 'fseek' with no prototype
Warning MAIN.C 37: Call to function 'fgetc' with no prototype
Warning MAIN.C 40: Call to function 'fgetc' with no prototype
Warning MAIN.C 44: Call to function 'fseek' with no prototype
Warning MAIN.C 46: Call to function 'malloc' with no prototype
Warning MAIN.C 49: Call to function 'fprintf' with no prototype
Warning MAIN.C 50: Call to function 'exit' with no prototype
Warning MAIN.C 53: Call to function 'fscanf' with no prototype
Warning MAIN.C 55: Call to function 'fprintf' with no prototype
Warning MAIN.C 56: Call to function 'exit' with no prototype
Warning MAIN.C 59: Call to function 'fscanf' with no prototype
Warning MAIN.C 61: Call to function 'fprintf' with no prototype
Warning MAIN.C 62: Call to function 'exit' with no prototype
Warning MAIN.C 65: Call to function 'fgetc' with no prototype
Error MAIN.C 68: Undefined symbol 'data'
Error MAIN.C 68: Undefined symbol 'GLubyte'
Error MAIN.C 68: Expression syntax
Warning MAIN.C 71: Call to function 'fprintf' with no prototype
Warning MAIN.C 72: Call to function 'exit' with no prototype
Error MAIN.C 75: Undefined symbol 'data'
Warning MAIN.C 75: Call to function 'fread' with no prototype
Warning MAIN.C 77: Call to function 'fprintf' with no prototype
Warning MAIN.C 78: Call to function 'exit' with no prototype
Warning MAIN.C 81: Call to function 'fclose' with no prototype


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 13-12-2004 à 12:17:35    


Ouep bien sur, voilà
 
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <GL/glut.h>
 
typedef struct {
    int sizeX, sizeY;
    GLubyte *data;
} PPMImage;
 
static PPMImage *LoadPPM(const char *filename)
{
    char buff[16];
    PPMImage *result;
    FILE *fp;
    int maxval,lig_comm=0;
 
    fp = fopen(filename, "rb" );
    if (!fp)
    {
 fprintf(stderr, "Unable to open file `%s'\n", filename);
 exit(1);
    }
 
    if (fread(buff, 1, 3, fp)!=3)
    {
 perror(filename);
 exit(1);
    }
 
    /*if (buff[0] != 'P' || buff[1] != '6')
    {
 fprintf(stderr, "Invalid image format (must be `P6')\n" );
 exit(1);
    }
*/
    if (buff[2] != 0x0a)
      fseek(fp,-1,SEEK_CUR);
 
    while (fgetc(fp) == '#'){
      lig_comm++;
      while (fgetc(fp) != '\n')
 ;
      }
 
    fseek(fp,-1,SEEK_CUR);
 
    result = (PPMImage *)malloc(sizeof(PPMImage));
    if (!result)
    {
 fprintf(stderr, "Unable to allocate memory\n" );
 exit(1);
    }
 
    if (fscanf(fp, "%d %d", &result->sizeX, &result->sizeY) != 2)
    {
 fprintf(stderr, "Error loading image `%s'\n", filename);
 exit(1);
    }
 
    if (fscanf(fp, "%d", &maxval) != 1)
    {
 fprintf(stderr, "Error loading image `%s'\n", filename);
 exit(1);
    }
 
    while (fgetc(fp) != '\n')
 ;
 
    result->data = (GLubyte *)malloc(3 * result->sizeX * result->sizeY);
    if (!result)
    {
 fprintf(stderr, "Unable to allocate memory\n" );
 exit(1);
    }
 
    if (fread(result->data, 3 * result->sizeX, result->sizeY, fp) != result->sizeY)
    {
 fprintf(stderr, "Error loading image `%s'\n", filename);
 exit(1);
    }
 
    fclose(fp);
 
    return result;
}
 
 
int main ( void )
{
 PPMImage *neb;
 int i;
 
 
 neb = LoadPPM("./bump_binary.ppm" );
 printf("H : %d, L %d, nb %d\n",neb->sizeY, neb->sizeX, strlen(neb->data));
 
 for ( i=0;i<strlen(neb->data)-4;i++) ;
  printf("%c",neb->data[i]);
 
  printf("FINI\n" );
 
 
}
 
ca devrait compiler
EDIT : l'include du Glut est pas necessaire


Message édité par Chandy le 13-12-2004 à 12:19:19
Reply

Marsh Posté le 13-12-2004 à 13:14:26    

Chandy a écrit :

Ouep bien sur, voilà

Code :
  1. #include <GL/glut.h>




On va se débrouiller... Essaye d'utiliser les boutons [C/C++] ou [Fixed] pour encadrer le code...

Citation :


Code :
  1. neb = LoadPPM("./bump_binary.ppm" );




Il faudrait donner un lien html vers ce fichier


Message édité par Emmanuel Delahaye le 13-12-2004 à 13:15:59

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 13-12-2004 à 13:52:14    


 
Voilà le lien sur l'image
Il faut juste la recréer en .ppm, sinon imageshack la prend pas ... ( Irfanview ou Paint le font très bien )
 
http://img112.exs.cx/img112/2232/bump5fn.png
 
EDIT: je viens de réessayer en mettant en blanc quelques pixels tout en haut à gauche ( peu importe le nombre), et la taille du data est bien le nombre de pixels blancs*3 ( car RVB ).
Bref, c'est bien la lecture d'un pixel noir qui pose pb  :cry:


Message édité par Chandy le 13-12-2004 à 14:24:37
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed