I am trying to learn image processing using c.
#include <stdio.h>
int main(){
FILE *streamIn;
streamIn=fopen("lena512.bmp","r");
//read imageHeader and colorTable
unsigned char header[54];//to store the image header
//unsigned char colorTable[1024];//to store the colorTable,if it exists
for(int i=0;i<54;i ){
header[i]=getc(streamIn);
}
/*
width of the image(18th byte)
height of the image(22nd byte)
bitDepth of the image(28th byte)
*/
int width=*(int*)(&header[18]);
int height=*(int*)(&header[22]);
int bitDepth=*(int*)(&header[28]);
}
I came across the line which i couldn't understand.
int width=*(int*)(&header[18]);
Why can't we simply do the type casting like int width=(int)(header[18]);?
CodePudding user response:
I came across the line which i couldn't understand.
int width=*(int*)(&header[18]);
Neither did the person who wrote it, because this is blatant undefined behavior in several different ways. It gives This gives a misaligned address (on mainstream systems) as well as a strict aliasing violation. What is the strict aliasing rule?
Those 3 lines at the end are bugs, you cannot write C code like that. The correct way to write this program might be to copy the data into pre-defined structs, provided by the OS API.
CodePudding user response:
You are using *(int*)(&header[18])
and you want to know why (int)(header[18])
can't be used.
Well, these are completely different expressions.
The first one takes the address of header[18]
, which is an unsigned char
, so this gives a pointer to such. Casting it to a pointer to int
and dereferencing it by *
in the assignment copies a complete int
starting at that address, reading all necessary bytes.
The second one simply reads the single unsigned char
in header[18]
and casts the value to an int
. This will use only the first byte.
Note: Microsoft's header files provide structure definitions of the BMP header. It's much better to use them. You can for example call fread()
to read the header.