如何计算 bfOffBits
How to Calculate bfOffBits
我正在尝试使用 C 手动读取和打开 BMP 文件,在阅读 BMP 规范并了解这些文件的工作原理后,header 对字节的定义等于 bfOffBits
和 biWidth
。因此,例如 bfOffBits
等于 4 个字节,在我的测试位图中为“8A 04 00 00”。我如何从这里得到图像偏移数据的十进制等效值?
我对 C 非常非常陌生,考虑到我工作的主要语言是 PHP,所以关于该语言如何工作的概念与我有很大不同,所以对我放轻松 :)
目前,我在 C 语言中使用这个函数,感觉完全错误,但对某些偏移值有效,对其他偏移值无效
int calculateBytes(int bytes[4]) {
int Value = bytes[0];
if (bytes[1] > 0) {
if (bytes[0] == 0) {
Value = 256;
}
Value = Value * bytes[1];
}
if (bytes[2] > 0) {
if (bytes[1] == 0) {
if (bytes[0] == 0) {
Value = 256;
}
Value = Value * 256;
}
Value = Value * bytes[2];
}
if (bytes[3] > 0) {
if (bytes[2] == 0) {
if (bytes[1] == 0) {
if (bytes[0] == 0) {
Value = 256;
}
Value = Value * 256;
}
Value = Value * 256;
}
Value = Value * bytes[3];
}
return Value;
}
你可以这样简单地做:
char bytes[] = {0x8A, 0x04, 0x00, 0x00};
int* p_int = (int*)bytes; // Unsafe version ,doesn't take into account endianness
int num2 = bytes[0] | ( (int)bytes[1] << 8 ) | ( (int)bytes[2] << 16 ) | ( (int)bytes[3] << 24 ); // Safe version
printf("%d %d\n", *p_int, num2);
所以你的函数看起来像这样:
int calculateBytes(int bytes[4]) {
int num = bytes[0]
| ( (int)bytes[1] << 8 )
| ( (int)bytes[2] << 16 )
| ( (int)bytes[3] << 24 );
return num;
}
张贴值“8A 04 00 00”看起来像 'little Endian'。
您使用的架构是'little Endian'。如果是这样,只需将值读入一个 int。否则,将4个字节的顺序颠倒。
然后使用类似以下内容打印结果值:printf(" offset: %d\n", myInt );
在 32 位架构上将 'little Endian' 转换为 'big Endian' 的简单方法。
int convert( char *pBytes )
{
int result = 0;
result = pBytes[3];
result <<= 8;
result += pBytes[2];
result <<= 8;
result += pBytes[1];
result <<= 8;
result += pBytes[0];
return( result );
} // end function: convert
我正在尝试使用 C 手动读取和打开 BMP 文件,在阅读 BMP 规范并了解这些文件的工作原理后,header 对字节的定义等于 bfOffBits
和 biWidth
。因此,例如 bfOffBits
等于 4 个字节,在我的测试位图中为“8A 04 00 00”。我如何从这里得到图像偏移数据的十进制等效值?
我对 C 非常非常陌生,考虑到我工作的主要语言是 PHP,所以关于该语言如何工作的概念与我有很大不同,所以对我放轻松 :)
目前,我在 C 语言中使用这个函数,感觉完全错误,但对某些偏移值有效,对其他偏移值无效
int calculateBytes(int bytes[4]) {
int Value = bytes[0];
if (bytes[1] > 0) {
if (bytes[0] == 0) {
Value = 256;
}
Value = Value * bytes[1];
}
if (bytes[2] > 0) {
if (bytes[1] == 0) {
if (bytes[0] == 0) {
Value = 256;
}
Value = Value * 256;
}
Value = Value * bytes[2];
}
if (bytes[3] > 0) {
if (bytes[2] == 0) {
if (bytes[1] == 0) {
if (bytes[0] == 0) {
Value = 256;
}
Value = Value * 256;
}
Value = Value * 256;
}
Value = Value * bytes[3];
}
return Value;
}
你可以这样简单地做:
char bytes[] = {0x8A, 0x04, 0x00, 0x00};
int* p_int = (int*)bytes; // Unsafe version ,doesn't take into account endianness
int num2 = bytes[0] | ( (int)bytes[1] << 8 ) | ( (int)bytes[2] << 16 ) | ( (int)bytes[3] << 24 ); // Safe version
printf("%d %d\n", *p_int, num2);
所以你的函数看起来像这样:
int calculateBytes(int bytes[4]) {
int num = bytes[0]
| ( (int)bytes[1] << 8 )
| ( (int)bytes[2] << 16 )
| ( (int)bytes[3] << 24 );
return num;
}
张贴值“8A 04 00 00”看起来像 'little Endian'。
您使用的架构是'little Endian'。如果是这样,只需将值读入一个 int。否则,将4个字节的顺序颠倒。
然后使用类似以下内容打印结果值:printf(" offset: %d\n", myInt );
在 32 位架构上将 'little Endian' 转换为 'big Endian' 的简单方法。
int convert( char *pBytes )
{
int result = 0;
result = pBytes[3];
result <<= 8;
result += pBytes[2];
result <<= 8;
result += pBytes[1];
result <<= 8;
result += pBytes[0];
return( result );
} // end function: convert