2015-03-13 81 views
1
unsigned char* Read_pixels(unsigned char *baseptr) 
{ 
    unsigned char pixelinfo[4096]; 

    pFileheader->ID1 = *baseptr++;   // save B 
    pFileheader->ID2 = *baseptr++;   // save M 

    pFileheader->FileSize = *((unsigned int*)baseptr); 
    baseptr = baseptr + 4; 

    pFileheader->Reserved = *((unsigned short*)baseptr); 
    baseptr = baseptr + 2; 

    pFileheader->Reserved2 = *((unsigned short*)baseptr); 
    baseptr = baseptr + 2; 

    pFileheader->PxOffset = *((unsigned int*)baseptr); 

} 

在这个READ BMP函数中,我收到一个指向内存中bmp文件开始的指针。 我在上面的代码中做的是读取fileheader并将数据存储在fileheader结构的相应成员中。我有一个疑问,在第五行代码中,我将一个char指针指向一个unsigned int.I,因为FileSize值是unsigned int类型的,我的baseptr实际上是一个char指针。我做对了吗?代码是否正确?函数读取bmp文件标头

回答

0

这是正确的如果您的目标机器的字节顺序与BMP标头内的字节顺序相同。在这种情况下,对于小型机器来说是正确的,这是x86 PC的情况。

如果您正在为使用big endian的目标机器进行编译,那么不幸的是,除了读取生成该单词的四个字节并重新组合它们以形成您愿意使用的32位整数。

一个可移植的方式将它使用预处理器,并具有地方做:

#ifdef BIG_ENDIAN 
    length = ((length << 24) & 0xff000000) /* Swap the 4 bytes within the word */ 
      | ((length << 8) & 0x00ff0000) 
      | ((length >> 8) & 0x0000ff00) 
      | ((length >> 24) & 0x000000ff); 
#endif 

另外,如果我是你,我会在完全匹配的BMP头的结构使用memcpyfread找时间做它领域,远远超过copingy每个单独场:)

最后最后再提醒一下,使用类型,如uint32_t代替unsigned int,这向你保证,你使用的是32位int更优雅,因为有些机器使用16位整型你需要long得到一个32位整数。

+0

非常感谢你 – 2015-03-13 11:10:29

+0

我打算在ARM上使用它...所以它的一个32位int – 2015-03-13 11:15:12

+0

是的,并且字节顺序取决于系统。大多数情况下,ARM是连接起来的,所以他们使用小端序,但并非总是如此,所以你一定要检查一下! – Bregalad 2015-03-13 11:46:14

0

你的疑惑是有道理的。通过这种方式进行投射,假设您的输入文件和运行的计算机具有相同的字节顺序。

安全的事情是不要假设什么而不是首先使用演员。有二进制数据转换为“平台”字节序的标准函数(ntohlntohshtonl,htons),如果不需要转换,则不执行任何操作,否则转换。这是可行的,因为目标操作系统的实现知道系统运行的是什么字节序。

或者,一次只消耗一个字节的较大值,并将它们以字节顺序不连续的顺序连接起来。 ( “不了解” 为你的程序;输入字节顺序必须是已知的!)

例如:

pFileheader->FileSize = (unsigned int)baseptr[0] + 
    (((unsigned int)baseptr[1])<<8) + 
    (((unsigned int)baseptr[2])<<16) + 
    (((unsigned int)baseptr[3])<<24); 
    baseptr = baseptr + 4; 

pFileheader->Reserved =(unsigned int)baseptr[0] + 
    (((unsigned int)baseptr[1])<<8); 
    baseptr = baseptr + 2; 

等。如果使用了很多,写一个函数或宏来读取一个字或32位int。