C reading bmp files

六月ゝ 毕业季﹏ 提交于 2019-12-05 23:29:10

Check the padding of the structure for the header. You may find that the compiler has aligned the fileSize value in the struct to a 4-byte boundary within the structure. You can see this if you put in some debug printf's of the structure element addresses.

I ran an example using your struct here:

typedef struct {
    byte        sigB;
    byte        sigM;
    int32_t     fileSize;
    int16_t     resv1;
    int16_t     resv2;
    int32_t     pixelOffset;
} tBmpHeader;

tBmpHeader hdr;

int main(int argc, char *argv[])
{
    printf("%d\n", sizeof(tBmpHeader) );
    printf("%p hdr\n", &hdr);
    printf("%p sigB\n", &hdr.sigB);
    printf("%p sigM\n", &hdr.sigM);
    printf("%p fileSize\n", &hdr.fileSize);
    printf("%p resv1\n", &hdr.resv1);
    printf("%p resv2\n", &hdr.resv2);
    printf("%p pixelOffset\n", &hdr.pixelOffset);
}

With the output:

16
0x8049788 hdr
0x8049788 sigB
0x8049789 sigM
0x804978c fileSize
0x8049790 resv1
0x8049792 resv2
0x8049794 pixelOffset

There is a 4-byte offset between the beginning of hdr and the fileSize element, so there are two bytes of padding before fileSize.

The thing to do is read the header a date item at a time. You can maintain some "structure" to the code by encapsulating the reads in a single function (e.g., "readBmpHeader(...)"). You can keep the struct but read each field separately. So, you would do (I leave off the return value checks for clarity of example):

FileRead(file, &pBmp->header.sigB, sizeof(byte), 1)
FileRead(file, &pBmp->header.sigB, sizeof(byte), 1)
FileRead(file, &pBmp->header.fileSize, sizeof(int32_t), 1)
FileRead(file, &pBmp->header.resv1, sizeof(int16_t), 1)
FileRead(file, &pBmp->header.resv2, sizeof(int16_t), 1)
FileRead(file, &pBmp->header.pixelOffset, sizeof(int32_t), 1)

You should never use direct I/O with structures: just because you've declared your struct in the same order as the BMP headers, there's no guarantee that your compiler has the fields end-to-end with nothing in between.

Compilers frequently adhere to a platform's alignment restrictions, which might cause them to add padding bytes between fields to make sure e.g. a large field's starting address is aligned.

You need to either use compiler-specific magic to force the structure to be "packed", or byte-by-byte I/O into the structure.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!