So ive already read a number of the questions that relate to this but none of them have solved my problem. Im currently attempting to read in a P6 ppm file (Its a binary file). My current code is
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct pixel {
char red;
char green;
char blue;
};
int main(int argc, char **argv)
{
char type[3];
int numRow, numCol, maxNum;
FILE *oldFile, *newFile;
struct pixel currentPixel;
char buffer[5];
oldFile = fopen(argv[1], "rb");
if(oldFile == NULL) {
fprintf(stderr, "Could not open file %s for reading in binary", argv[1]);
return 0;
}
fscanf(oldFile, "%2s", type);
type[2] = '\0';
if(strcmp(type, "P6") != 0) { //Make sure we have a P6 file
printf("This file is not of type P6");
return 0;
}
newFile = fopen(argv[2], "wb");
fprintf(newFile, "%s\n", type);
/*Read number of columns
rows and
The max number that can represent a colour*/
fscanf(oldFile, "%d", &numCol);
fscanf(oldFile, "%d", &numRow);
fscanf(oldFile, "%d", &maxNum);
/*Print the information to newFile*/
fprintf(newFile, "%d %d\n", numCol, numRow);
fprintf(newFile, "%d\n", maxNum);
fseek(oldFile, 1, SEEK_CUR);
fread(¤tPixel, sizeof(struct pixel), 1, oldFile);
printf("%c %c %c", currentPixel.red, currentPixel.green, currentPixel.blue);
fclose(newFile);
fclose(oldFile);
return 0;
}
So the beginning works and my newFile contains the lines P6, 3 3, and 255. I then try to read in the actual pixels with the fread
line. This is where it fails and im not sure why. It currently prints out two question marks inside of a diamond. I am currently only trying to read in the first three numbers which make up one pixel (one red component one green and one blue).
I also have a P3 file of the same picture and the P3 file looks like:
P3
3 3
255
0 255 255 0 0 0 0 0 255
255 0 255 100 100 100 255 0 0
255 255 0 255 255 255 0 255 0
So the binary file should be set up like this but just in binary format. When i type in
od -c binaryImage.ppm
I get
0000000 P 6 \n 3 3 \n 2 5 5 \n \0 377 377 \0 \0
0000020 \0 \0 \0 377 377 \0 377 X X X 377 \0 \0 377 377 \0
0000040 377 377 377 \0 377 \0
0000046
Im not sure why my fread function is not working.Not sure if relevant but i am compiling on Linux Ubuntu with
gcc -Wall rotate.c -o rotate
You are printing RGB values as characters instead as numbers. Keep them as unsigned char
(because they have values between [0-255]) in the structure, but use %d
when printing. You should use printf
as follows:
printf("%d %d %d", currentPixel.red, currentPixel.green, currentPixel.blue);
Also I recommend do not use a structure to read the RGB values because the compiler will probably add a padding byte to align the structure to the machine word (e.g. 32 bits). In 32 bits systems, you will read 4 bytes. You can check this printing the sizeof(struct pixel)
. To read more about structure alignment you could check the Wikipedia article Data Structure Alignment.
Instead a struct, use a char
array:
unsigned char currentPixel[3];
...
fread(currentPixel, 3, 1, oldFile);
printf("%d %d %d", currentPixel[0], currentPixel[1], currentPixel[2]);
Also, if you need to read the entire image, create an array of unsigned char
with size number of pixels x 3
. The 3 is the number of bytes for the RGB tuple. If the PPM format include some padding at the end of each line, you need to consider this too.