我正在尝试编写一个程序,使用 C 将 p3 PPM 文件转换为 P6。但我遇到了两个问题。 1,我的代码中出现段错误。和 2,标题没有被正确读入转换后的 p6 文件。这是我的头文件。
#ifndef PPM_UTILS
#define PPM_UTILS
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
// First meaningful line of the PPM file
typedef struct header {
char MAGIC_NUMBER[3];
unsigned int HEIGHT, WIDTH, MAX_COLOR;
} header_t;
// Represents an RGB pixel with integer values between 0-255
typedef struct pixel {
unsigned int R, G, B;
} pixel_t;
// PPM Image representation
typedef struct image {
header_t header;
pixel_t* pixels;
} image_t;
header_t read_header(FILE* image_file);
image_t* read_ppm(FILE* image_file);
image_t* read_p6(FILE* image_file, header_t header);
image_t* read_p3(FILE* image_file, header_t header);
void write_header(FILE* out_file, header_t header);
void write_p6(FILE* out_file, image_t* image);
void write_p3(FILE* out_file, image_t* image);
#endif
我将代码的主要部分拆分为两个文件,并在编译器中合并
#include <stdio.h>
#include "ppm_utils.h"
header_t read_header(FILE* image_file)
{
header_t header;
fscanf(image_file, "%c %d %d %d",header.MAGIC_NUMBER, &header.WIDTH, &header.HEIGHT, &header.MAX_COLOR);
return header;
}
void write_header(FILE* out_file, header_t header)
{
fprintf(out_file, "%c %d %d %d", *header.MAGIC_NUMBER,header.HEIGHT,header.WIDTH,header.MAX_COLOR);
}
image_t* read_ppm(FILE* image_file)
{
header_t header = read_header(image_file);
image_t* image = NULL;
if (strcmp("P3", header.MAGIC_NUMBER) == 0)
{
image = read_p3(image_file, header);
}
else if (strcmp("P6", header.MAGIC_NUMBER) == 0)
{
image = read_p6(image_file, header);
}
return image;
}
image_t* read_p6(FILE* image_file, header_t header)
{
int size;
size = header.HEIGHT * header.WIDTH;
image_t* image = (image_t*) malloc (sizeof(image_t));
image -> header = header;
image -> pixels = (pixel_t*) malloc (sizeof(pixel_t)* size);
char r,g,b;
r = 0;
g = 0;
b = 0;
int i;
for (i=0;i<size;i++){
fscanf(image_file, "%c%c%c", &r, &g, &b);
image -> pixels -> R = (int) r;
image -> pixels -> G = (int) g;
image -> pixels -> B = (int) b;
}
return image;
}
image_t* read_p3(FILE* image_file, header_t header)
{
int size;
size = header.HEIGHT * header.WIDTH;
image_t* image = (image_t*) malloc (sizeof(image_t));
image -> header = header;
image -> pixels = (pixel_t*) malloc (sizeof(pixel_t)* size);
int r,g,b;
r = 0;
g = 0;
b = 0;
int i;
for (i=0;i<size;i++){
fscanf(image_file, "%d %d %d ", &r, &g, &b);
image -> pixels -> R = (int) r;
image -> pixels -> G = (int) g;
image -> pixels -> B = (int) b;
}
return image;
}
void write_p6(FILE* out_file, image_t* image)
{
header_t header = image -> header;
header.MAGIC_NUMBER[1]=6;
write_header(out_file, header);
int size = header.HEIGHT * header.WIDTH;
int i;
for (i=0;i<size;i++){
fprintf(out_file,"%c%c%c", (char) image->pixels->R, (char) image->pixels->G, (char) image->pixels->B);
}
}
void write_p3(FILE* out_file, image_t* image)
{
header_t header = image -> header;
header.MAGIC_NUMBER[1]=3;
write_header(out_file, header);
int size = header.HEIGHT * header.WIDTH;
int i;
for (i=0;i<size;i++){
fprintf(out_file,"%d %d %d ",image->pixels->R,image->pixels->G,image->pixels->B);
}
}
..
#include <stdio.h>
#include "ppm_utils.h"
int main(int argc, char *argv[])
{
if (argc != 3)
{
printf("The program needs two arguments");
return 1;
}
FILE *fr;
fr = fopen(argv[1],"r");
if (fr == NULL)
{
printf("The opening failed");
}
FILE *fw;
fw = fopen(argv[2],"w");
if (fw == NULL)
{
printf("The opening failed");
}
image_t* image = read_ppm(fr);
write_p6(fw,image);
free(image);
free(image->pixels);
fclose(fr);
fclose(fw);
return 0;
}
你们有什么解决办法吗?
最佳答案
读取头部时需要指定要读取的魔数(Magic Number)的字符数:
fscanf(image_file, "%2c %d %d %d",header.MAGIC_NUMBER, &header.WIDTH, &header.HEIGHT, &header.MAX_COLOR);
要与 strcmp()
一起使用,数组中的最后一个字节必须设置为 0:
header.MAGIC_NUMBER[2] = 0;
写header的时候需要写成字符串:
fprintf(out_file, "%s %d %d %d", header.MAGIC_NUMBER,header.HEIGHT,header.WIDTH,header.MAX_COLOR);
关于使用 C 将 ppm 文件从 P3 转换为 P6,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48511809/