Mike Smith Mike Smith - 2 months ago 14
C Question

Reading and writing BMP files in C memory error

I am attempting to write a program to invert the color of an image. My problem is when I try to read from the DIB header in my BMP file.

When I try to get the file header size and use fread(dib.fileheader, 4,1,fp); . I get an error that says "The memory could not be written". I have attached it for further clarification.

enter image description here

Here is my code:

#include <stdio.h>
#include <string.h>


struct BMP {
char filetype[2]; // must be BM, must check if BM
unsigned int filesize;
short reserved1;
short reserved2;
unsigned int dataoffset;

};

struct DIB {
unsigned int fileheader;
unsigned int headersize;
int width;
int height;
short planes;
short bitsperpixel; /* we only support the value 24 here */
unsigned int compression; /* we do not support compression */
unsigned int bitmapsize;
int horizontalres;
int verticalres;
unsigned int numcolors;
unsigned int importantcolors
};
struct pixel {
int val;
char * def;
struct listitem * next;
};


void invertImage(char fileName[]){

struct BMP bmp;
struct DIB dib;


FILE *fp = fopen(fileName, "rb");

//FileType
fread(bmp.filetype, 1,2,fp);
printf("Value is %c\n", bmp.filetype[1]);

//Check if file format is BM
if(bmp.filetype[0] != 'B' && bmp.filetype[1] !='M'){
printf("Wrong format");
}
//Size of the file in bytes
fread(bmp.filesize, 4,1,fp);
printf("Value is %d\n", bmp.filesize);
//Go to dataoffset
fseek(fp,10,SEEK_CUR);

fread(bmp.dataoffset, 4,1,fp);
printf("Offset is %d\n", bmp.dataoffset);


fread(dib.fileheader, 4,1,fp);
printf("File header is %d bytes\n", dib.fileheader);


fclose(fp);

}

int main(int argc, char *argv[] ){

printf("Program name %s\n", argv[0]);


if( strcmp(argv[1],"-invert") == 0) {
printf("Invert\n");
printf("File name is %s\n", argv[2] );

invertImage(argv[2]);

}

else {
printf("Greyscale\n");
//greyScaleImage();
}

return 0;

}


Also here is the output to my program.

enter image description here

Answer

fread expects a pointer to memory to write the file contents. So you need to give it the address of dib.fileheader

fread( &dib.fileheader, sizeof(dib.fileheader),1,fp );
printf("File header is %d bytes\n", dib.fileheader);

It's complaining because it's interpreting whatever is in dib.fileheader as the address to write to, which may or may not be valid for your program.

Note that the following is ok as it stands because bmp.filetype is already a pointer to char - it's a char[]

fread(bmp.filetype, 1,2,fp);
printf("Value is %c\n", bmp.filetype[1]);

To make it a bit more general, you could write

fread(bmp.filetype, sizeof(bmp.filetype), 1, fp);
printf("Value is %c\n", bmp.filetype[1]);