2015-11-08 1 views
2

J'ai déjà lu un certain nombre de questions qui se rapportent à cela, mais aucune d'elles n'a résolu mon problème. Im essayant actuellement de lire dans un fichier P6 ppm (c'est un fichier binaire). Mon code actuel estLecture d'un fichier ppm binaire P6

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

struct pixel { 
    char red; 
    char green; 
    char blue; 
}; 

int main(int argc, char **argv) 
{ 
    char type[3]; 
    int numRow, numCol, maxNum; 
    FILE *oldFile, *newFile; 
    struct pixel currentPixel; 
    char buffer[5]; 

    oldFile = fopen(argv[1], "rb"); 
    if(oldFile == NULL) { 
     fprintf(stderr, "Could not open file %s for reading in binary", argv[1]); 
     return 0; 
    } 
    fscanf(oldFile, "%2s", type); 
    type[2] = '\0'; 
    if(strcmp(type, "P6") != 0) { //Make sure we have a P6 file 
     printf("This file is not of type P6"); 
     return 0; 
    } 

    newFile = fopen(argv[2], "wb"); 
    fprintf(newFile, "%s\n", type); 
    /*Read number of columns 
    rows and 
    The max number that can represent a colour*/ 
    fscanf(oldFile, "%d", &numCol); 
    fscanf(oldFile, "%d", &numRow); 
    fscanf(oldFile, "%d", &maxNum); 
    /*Print the information to newFile*/ 
    fprintf(newFile, "%d %d\n", numCol, numRow); 
    fprintf(newFile, "%d\n", maxNum); 
    fseek(oldFile, 1, SEEK_CUR); 

    fread(&currentPixel, sizeof(struct pixel), 1, oldFile); 
    printf("%c %c %c", currentPixel.red, currentPixel.green, currentPixel.blue); 

    fclose(newFile); 
    fclose(oldFile); 
    return 0; 
} 

Ainsi, les œuvres de début et de mon newFile contient les lignes P6, 3 3 et 255. J'essaie ensuite de lire les pixels réels avec la ligne fread. C'est là que ça échoue et je ne sais pas pourquoi. Il imprime actuellement deux points d'interrogation à l'intérieur d'un diamant. Actuellement, j'essaie seulement de lire dans les trois premiers chiffres qui composent un pixel (un composant rouge un vert et un bleu).

J'ai aussi un fichier P3 de la même image et le fichier P3 ressemble:

P3 

3 3 

255 

    0 255 255 0 0 0 0 0 255 

255 0 255 100 100 100 255 0 0 

255 255 0 255 255 255 0 255 0 

Ainsi, le fichier binaire doit être mis en place comme cela, mais juste au format binaire. Quand je tape dans

od -c binaryImage.ppm

Je reçois

0000000 P 6 \n 3  3 \n 2 5 5 \n \0 377 377 \0 \0 
0000020 \0 \0 \0 377 377 \0 377 X X X 377 \0 \0 377 377 \0 
0000040 377 377 377 \0 377 \0 
0000046 

Im ne sais pas pourquoi ma fonction fread ne working.Not que le cas échéant, mais je suis compilait sur Linux Ubuntu avec

gcc -Wall -o rotate.c faites pivoter

+0

@WeatherVane Les trois premières lignes sont du texte normal. La lecture de ceux avec 'fscanf' fonctionne bien, mais après cela, nous devons lire' fread' car le reste du fichier est écrit en binaire – JackVanier

+0

Pourquoi imprimez-vous les valeurs RVB sous forme de caractères (% c) à la place de nombres (% d)? C'est la raison pour laquelle vous obtenez des symboles étranges dans la sortie. –

+0

@BrunoBellucci C'est une bonne question. J'ai changé mon code donc au lieu de rouge, vert et bleu étant char je les ai fait int. Il imprime maintenant '16776960 0 -16711681' – JackVanier

Répondre

2

Vous imprimez des valeurs RVB sous forme de caractères à la place de nombres. Conservez-les sous la forme unsigned char (car leur valeur est comprise entre [0 et 255]) dans la structure, mais utilisez %d lors de l'impression. Vous devez utiliser printf comme suit:

printf("%d %d %d", currentPixel.red, currentPixel.green, currentPixel.blue); 

Aussi je recommande de ne pas utiliser une structure pour lire les valeurs RVB parce que le compilateur probablement ajouter un octet de remplissage pour aligner la structure du mot machine (par exemple 32 bits). Dans les systèmes 32 bits, vous lirez 4 octets. Vous pouvez vérifier cette impression le sizeof(struct pixel). Pour en savoir plus sur l'alignement de la structure, vous pouvez consulter l'article Wikipedia Data Structure Alignment.

plutôt une struct, utiliser un tableau char:

unsigned char currentPixel[3]; 
... 
fread(currentPixel, 3, 1, oldFile); 
printf("%d %d %d", currentPixel[0], currentPixel[1], currentPixel[2]); 

En outre, si vous avez besoin de lire l'ensemble de l'image, créez un tableau de unsigned char avec la taille number of pixels x 3. Le 3 est le nombre d'octets pour le tuple RGB. Si le format PPM inclut un remplissage à la fin de chaque ligne, vous devez également prendre cela en compte.

+0

Ne devrait pas la ligne 'printf ("% c% c% c ", currentPixel [0], currentPixel [1], currentPixel [2]);' être 'printf ("% d% d% d ", currentPixel [0], currentPixel [1], currentPixel [2]);'? – JackVanier

+0

Vous avez raison, mon erreur (copier-coller). –

+0

D'accord merci je l'ai maintenant – JackVanier