Win32 C/C ++从字节数组读取BMP宽度和高度 [英] Win32 C/C++ Reading BMP width and height from a byte array
问题描述
我已将BMP文件读入字节数组.因此,在研究了这个问题的答案之后:将字节数组转换为int c ++ .是从 BMP信息标头获取宽度和高度的方法吗?安全正确吗?
long width, height;
memcpy(&width, &bmp[0x12], sizeof(long));
memcpy(&height, &bmp[0x16], sizeof(long));
这种方法会带来什么问题?
long* width = (long*)(&bmp[0x12]);
long* height= (long*)(&bmp[0x16]);
根据 Wikipedia BMP文件格式,0x12
为位图宽度的偏移量(以像素为单位),0x16
位图高度的偏移量(以像素为单位).
PD.我已经找到了从内存缓冲区加载位图的解决方案,但是我我想保持代码简单,因为我只需要位图的宽度,高度和原始数据,而且我也不知道该答案是否安全.
谢谢!
这两种方法本质上都是相同的,并且都具有相同的基本问题:如果主机系统的字节序与BMP的字节序不同,则这两种方法将不起作用文件用途.直接访问大于二进制格式的单个字节的值始终是问题.
后一种方法还具有另一个缺点,即如果主机无法在生成的地址上进行long
访问,则可能会中断.
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;
}
为了简洁起见,上面使用了C99的中号,将其移植回C89并不容易.
以上内容适用于 any 架构,因为它不再进行直接访问.相反,它假定buffer
包含小尾数格式的字节,我相信这是x86起源的BMP格式始终使用的字节.因此,即使在大端机上也可以使用.由于所有访问都是字节大小的,因此它也不再可能对大内存访问进行未对齐的操作.
I have read a BMP file into a byte array. So after looking into the answers of this question: byte array to int c++. Is this way of obtaining the widht and height from a BMP information header safe and correct?
long width, height;
memcpy(&width, &bmp[0x12], sizeof(long));
memcpy(&height, &bmp[0x16], sizeof(long));
And what problems could this approach bring?
long* width = (long*)(&bmp[0x12]);
long* height= (long*)(&bmp[0x16]);
According to Wikipedia BMP file format, 0x12
is the offset of the bitmap width in pixels, and 0x16
the offset of the bitmap height in pixels.
PD. I have found this solution for loading the bitmap from memory buffer but I want to keep the code simple because I only need the width, the height and the raw data of the bitmap, and I do not know if that answer is safe either.
Thanks!
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.
这篇关于Win32 C/C ++从字节数组读取BMP宽度和高度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!