Sorry for my bad English.
Im trying to read a .bmp file in a C code using gcc on Linux (Fedora 27) but it doesn't work, the specific problem is when I use "fread()". I run the same code on raspbian (4.9.2-10) and magically works, read and write a .bmp file correctly. I really don't know what happening, I need help, please :'(
I use this image: https://mega.nz/#!c5hVEYTb!u4Mc3JxvrHxxpaMLpH8A-KS3_bb72_Nj9bHv1x-2keU
This is the code:
#include <stdio.h>
#include <stdlib.h>
#pragma pack(push, 1)
typedef struct Pix
{
unsigned char R;
unsigned char G;
unsigned char B;
unsigned char L;
int BW;
}Pix;
#pragma pack(pop)
#pragma pack(push, 1)
typedef struct BitMap
{
short Signature;
long Reserved1;
long Reserved2;
long DataOffSet;
long Size;
long Width;
long Height;
short Planes;
short BitsPerPixel;
long Compression;
long SizeImage;
long XPixelsPreMeter;
long YPixelsPreMeter;
long ColorsUsed;
long ColorsImportant;
struct Pix *pixels;
}BitMap;
#pragma pack(pop)
int main(int argc, char **argv)
{
unsigned long int i=0;
unsigned long int S=0;
struct BitMap source_info;
struct Pix source_pix;
FILE *fp;
FILE *Dfp;
fp=fopen("in.bmp","rb");
if (fp==NULL)
{
fputs("File error:", stderr);
exit(1);
}
Dfp=fopen("out.bmp","wb");
//I think maybe in this line is the problem:
fread(&source_info, sizeof(source_info),1,fp);
S=source_info.Width*source_info.Height;
source_info.pixels = (struct Pix *) malloc(sizeof(struct Pix)*S);
for(i=1;i<=S;i++)
{
//read pixel from the source file
fread(&source_pix,sizeof(struct Pix),1,fp);
source_info.pixels[i-1] = source_pix;
}
fwrite(&source_info, sizeof(BitMap),1,Dfp);
// write pixels to destination file
for(i=1;i<=S;i++)
{
fwrite(&source_info.pixels[i-1],sizeof(struct Pix),1,Dfp);
}
fclose(fp);
fclose(Dfp);
return 0;
}
You are not using fixed size types between architectures. For example on a 32-bit platform long
is 32 bit, but on 64-bit long
is 64 bit, which is why on a 64-bit platform it can not read the headers correctly. The solution is to use the defines in stdint
.
#include <stdint.h>
#pragma pack(push, 1)
typedef struct Pix
{
uint8_t R, G, B;
int32_t BW;
}
Pix;
typedef struct BitMap
{
int16_t Signature;
int32_t Reserved1;
int32_t Reserved2;
int32_t DataOffSet;
int32_t Size;
int32_t Width;
int32_t Height;
int16_t Planes;
int16_t BitsPerPixel;
int32_t Compression;
int32_t SizeImage;
int32_t XPixelsPreMeter;
int32_t YPixelsPreMeter;
int32_t ColorsUsed;
int32_t ColorsImportant;
struct Pix *pixels;
}
BitMap;
#pragma pack(pop)