我有一项作业(不是针对我当前正在上的课程,而是针对我前一年发现的用于练习的作业),要求我使用
fread
读取 PPM 中的数据文件。
这是 PPM:
测试.ppm
P6
# Created by GIMP version 2.10.24 PNM plug-in
4 4
255
dÿÿÿ¯¯ÿÿÿÿÿ
我从文件中复制过去可能会导致此处呈现的方式出现问题 - 我不确定是否应该尝试对此采取任何措施。 但如果没问题的话,我会假设人们知道最后一行只是“一些二进制数据”,并继续描述我想要做的事情。
分配的作业包含一定量的代码,我不应该编辑这些代码来完成所描述的作业。
一方面,我们得到了
struct ppm_pixel {
union {
struct {
unsigned char red;
unsigned char green;
unsigned char blue;
};
unsigned char colors[3];
};
};
我们还给出了以下函数原型。
struct ppm_pixel* read_ppm(const char* filename, int* w, int* h)
我们要实施。 它应该返回一个像素矩阵(通过为 2D 数组动态分配空间并处理索引,以便以 2D 方式存储像素)。
我们还被指示“使用
fread
将所有像素数据作为一个大块复制到您的数组中”。
我认为如果我一次可以读取一个字节,我就可以做到这一点,但我似乎很难将所有内容作为一个大块读取,而且还用它来构造像素矩阵。 这是我到目前为止所写的内容。
read_ppm.c
struct ppm_pixel* read_ppm(const char* filename, int* w, int* h) {
FILE *fp;
char format[MAX_LINE_LENGTH];
int width, height, maxColorValue;
struct ppm_pixel *image;
fp = fopen(filename, "rb");
if (fp == NULL) {
perror("Error opening file");
return 1;
}
fscanf(fp, "%s\n", format);
if (strcmp(format, "P6") != 0) {
fprintf(stderr, "Invalid PPM format\n");
fclose(fp);
return 1;
}
char line[MAX_LINE_LENGTH];
fgets(line, sizeof(line), fp);
while (line[0] == '#') {
fgets(line, sizeof(line), fp);
}
*w = atoi(strtok(line, " "));
*h = atoi(strtok(NULL, " "));
fscanf(fp, "%d\n", &maxColorValue);
image = malloc(width * height * sizeof(struct ppm_pixel));
if (image == NULL) {
fprintf(stderr, "Memory allocation failed\n");
fclose(fp);
return 1;
}
fread(image, 3*8, width * height, fp);
fclose(fp);
fp = NULL;
return image;
}
我知道这是错误的,即使类型与接收原始数据而不是
image
实例不匹配。但这正是问题所在——如何才能既“作为一个块读入”,又将其构造成一个像素,然后将该像素分配到矩阵中? 我想您可以将原始数据读入 second 矩阵,然后从第二个矩阵复制到 struct ppm_pixel
中,但这似乎非常浪费内存和时间,不是吗?
如何使用
image
将数据作为一个块读取,并将其构造为
fread
结构体,并将 ppm_pixel
分配给矩阵? 是否应该通过将数据分配到另一个矩阵来完成,还是有更简单、更有效的方法?我认为可能有两个错误,一个是使用
ppm_pixel
,所以当我使用
fscanf
时,我认为这使得 fgets
正确跟踪文件中的正确位置。 另外,我在打印矩阵中的值时犯了一个愚蠢的错误。