用C中的fread读取ppm文件



我正在用fread读取一个ppm文件,并得到文件中没有的东西。我的代码如下:

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 memoryn");
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 memoryn");
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("P3n");
printf("%d %dn", img->width, img->height);
printf("%dn", 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");
}

当我尝试读取此文件时:

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     

我的read_image的结果是这样的(我通过print_image函数打印结果(:

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  

我用错fread了吗?或者我遗漏了流程的哪一部分?谢谢,提前。

IIRC,在.ppm文件中,几何体/格式可以在多行[或单行]上。

所以,用fgets读取它是行不通的。对整个格式使用fscanf

此外,IIRC,实际数据是二进制压缩的,因此您的测试文件并不是真正的PPM[如果它真的像您的数据块所显示的那样具有像素值的ascii文本]。

数据的实际格式没有嵌入换行符,所以不能执行fgetc,只能执行fread

看看我的答案:如何用C制作ppm文件的黑白图片?

最新更新