At fixed locations in the file metadata, there are three important integers, each stored using exactly 4 bytes:
At byte offset 10-13, the offset in the bitmap file where the pixel array starts.
At byte offset 18-21, the width of the image, in pixels.
At byte offset 22-25, the height of the image, in pixels.
/*
* Read in the location of the pixel array, the image width, and the image
* height in the given bitmap file.
*/
void read_bitmap_metadata(FILE *image, int *pixel_array_offset, int *width, int *height) {
fseek(image, 10, SEEK_SET);
fread(pixel_array_offset, 4, 1, image);
fseek(image, 18, SEEK_SET);
fread(width, 4, 1, image);
fseek(image, 22, SEEK_SET);
fread(height, 4, 1, image);
}
Do I have to use fseek
3 times here, even notice that the width and height are continuously?
No, you can omit the last fseek()
.
The fread()
advances the file position always by the amount of data read. So you only need to fseek()
when you want to skip some bytes or when you want to seek to a fixed position and you do not care where you currently are.
Since you only skip a few bytes you may as well just do a single fread()
from offset 0 of 26 bytes into a buffer and then pick the data from the buffer as you need it.
Endianness warning: There is one big issue when reading multi-byte integers from a file: Whether this works or not depends on the file-endianness and on the host-endianness. Your code only works when they match. If they do not match you have to swap the bytes after the fread()
operation. On Linux you have bswap_32()
for this, or if the endianness in the file is big endian (aka network byte order) you can use ntohl()
.