I am trying to write a program that converts a p3 PPM file to P6 using C. But I am running into two problems. 1, I am getting a segmentation fault in my code. and 2, the header isn't being properly read into the converted p6 file. Here is my header file.
#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
And I have the main part of the code split between two files that I combine in the compiler
#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;
}
Do you guys have any solutions?