简体   繁体   中英

reading ppm file with fread in C

I am reading a ppm file with fread and getting the things which are not in the file. My code is as follows:

typedef struct {
        int red;
        int green;
        int blue;
} Pixel;

typedef struct {
        int width;
        int height;
        int max_value;
        Pixel *p;
} Image;


Image* read_image(char *filename)
{
    char buff[16];
    Image *img;
    FILE *fp;
    int c, rgb_comp_color;
    //open PPM file for reading
    fp = fopen(filename, "rb");
    if (!fp) {
        fprintf(stderr, "Unable to open file '%s'\n", filename);
        exit(1);
    }

    //read image format
    if (!fgets(buff, sizeof(buff), fp)) {
        perror(filename);
        exit(1);
    }

    //check the image format
    if (buff[0] != 'P' || buff[1] != '3') {
        fprintf(stderr, "Invalid image format (must be 'P3')\n");
        exit(1);
    }

    //alloc memory form image
    img = (Image *)malloc(sizeof(Image));
    if (!img) {
        fprintf(stderr, "Unable to allocate memory\n");
        exit(1);
    }

    //read image size information
    if (fscanf(fp, "%d %d", &img->width, &img->height) != 2) {
        fprintf(stderr, "Invalid image size (error loading '%s')\n", filename);
        exit(1);
    }

    //read rgb component
    if (fscanf(fp, "%d", &img->max_value) != 1) {
        fprintf(stderr, "Invalid rgb component (error loading '%s')\n", filename);
        exit(1);
    }


    while (fgetc(fp) != '\n') ;
    //memory allocation for pixel data
    img->p = (Pixel*)malloc(img->width * img->height * sizeof(Pixel));

    if (!img) {
        fprintf(stderr, "Unable to allocate memory\n");
        exit(1);
    }

    //read pixel data from file
    if (fread(img->p, 3 * img->width, img->height, fp) != img->height) {
        fprintf(stderr, "Error loading image '%s'\n", filename);
        exit(1);
    }

    fclose(fp);
    return img;
}

void print_image(Image *img){
        printf("P3\n");
        printf("%d %d\n", img->width, img->height);
        printf("%d\n", img->max_value);

        for(int i=0; i<img->width*img->height; i++)
           printf("%d %d %d  ", img->p[i].red, img->p[i].green, img->p[i].blue);
        printf("\n");
}


When I try to read this file:

P3
 7
 7
 15

0    0    0     0    0    0     0    0    0     0    0    0     0    0    0     0    0    0     0    0    0     
0    3    3     3    3    0     0    7    7     7    7    0     0    11    11       11    11    0       0    15    15       
0    3    0     0    0    0     0    7    0     0    0    0     0    11    0        0    0    0     0    15    0        
0    3    3     3    0    0     0    7    7     7    0    0     0    11    11       11    0    0        0    15    15       
0    3    0     0    0    0     0    7    0     0    0    0     0    11    0        0    0    0     0    15    0        
0    3    0     0    0    0     0    7    7     7    7    0     0    11    11       11    11    0       0    15    0        
0    0    0     0    0    0     0    0    0     0    0    0     0    0    0     0    0    0     0    0    0     

The result of my read_image is this (I print the result by print_image function):

P3
7 7
15
538980362 540024864 807411744  538976288 538980361 540024864  807411744 538976288 538980361  540024864 807411744 538976288  538980361 540024864 807411744  538976288 538980361 540024864  807411744 538976288 538980361  540024864 807411744 538976288  538980361 540024864 807411744  538976288 540019209 857743392  538976288 538976307 540215584  857743392 538976288 538976304  3148064 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  0 0 0  

Am I using the fread wrong or what part of the proccess am I missing? Thanks, in advance.

IIRC, in a .ppm file, the geometry/format can be on multiple lines [or a single line].

So, doing fgets to read it won't work. Use fscanf for the entire format instead.

Also, IIRC, the actual data is packed binary, so your test file isn't really a PPM [if it truly has ascii text for the pixel values as your data block seems to show].

The real format for the data doesn't have embedded newlines, so you can't do the fgetc , just do fread .

See my answer: How to do a black-and-white picture of a ppm file in C?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM