Both approaches do essentially the same thing, and both have the same fundamental problem: won't work if the host system has a different byte-order than the BMP file uses. This is always the problem with directly accessing values larger than a single byte in binary format.
The latter approach also has the additional disadvantage of possibly breaking if the host cannot do a long
access at the resulting addresses.
In short, both "solutions" are bad. It's better to extract the value byte-by-byte and re-consititute it:
static uint32_t read_uint32_t(const uint8_t *buffer, size_t offset)
{
buffer += offset;
const uint32_t b0 = *buffer++;
const uint32_t b1 = *buffer++;
const uint32_t b2 = *buffer++;
const uint32_t b3 = *buffer++;
return (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
}
The above uses a smidgeon of C99 for brevity, porting it back to C89 is trivial.
Edit: the above works on any arcihtecture, since it's no longer doing direct accesses. Instead it assumes buffer
contains bytes in little-endian format, which I believe is what the x86-originated BMP format always uses. So, it will work even on a big-endian machine. It also no longer does possibly mis-aligned large memory accesses, since all accesses are just byte-sized which should work.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…