简体   繁体   中英

Reading information stored in header array when reading BMP file in c

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]);?

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM