Win32 C/C ++从字节数组读取BMP宽度和高度 [英] Win32 C/C++ Reading BMP width and height from a byte array

查看:121
本文介绍了Win32 C/C ++从字节数组读取BMP宽度和高度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已将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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆