解析位图文件时,如何替换 WORD 和 DWORD 数据类型?

Posted

技术标签:

【中文标题】解析位图文件时,如何替换 WORD 和 DWORD 数据类型?【英文标题】:When Parsing Bitmap files, how do I replace the WORD and DWORD data types? 【发布时间】:2012-09-08 21:39:11 【问题描述】:

在 Windows 中,您可以在尝试解析 bmp 文件时包含 windows.h 头文件,并且为您预定义了数据类型 WORD 和 DWORD(根据我的阅读内容)。在 linux 中,我需要使用这些 dataTypes,但我不知道如何定义它们并且不能包含 windows.h 标头。如何在 C++ 中执行此操作?

【问题讨论】:

【参考方案1】:

包含<stdint.h>,然后您可以将WORD 替换为uint16_t 并将DWORD 替换为uint32_t。当然还有BYTEuint8_t

如果需要,可以添加以下代码:

#include <stdint.h>
typedef uint32_t DWORD;
typedef uint16_t WORD;
typedef uint8_t BYTE;

但要小心!如果您想要可移植,您必须牢记多字节值的字节顺序。 Microsoft 代码几乎总是采用 little-endian,但 Linux 可以在 little-endian 和 big-endian 机器上运行。

更新

您在 cmets 中谈到的关于 BITMAPFILEHEADER 的新问题与字段的类型无关,而是与结构的 包装 有关:编译器可能会在字段之间添加填充字节结构以满足对齐(或其他要求)。

Microsoft 编译器将整数类型与其大小的倍数对齐。也就是说,WORDSHORT 值与 2 的地址倍数对齐,DWORDLONG 值与 4 的倍数对齐。

如果你看到你的结构的定义:

typedef struct 
    WORD    bfType;      //offset 0
    DWORD   bfSize;      //offset 4
    WORD    bfReserved1; //offset 8
    WORD    bfReserved2; //offset 10
    DWORD   bfOffBits;   //offset 12
 BITMAPFILEHEADER;

请注意,bfSize 字段的大小为 4 字节,因此它将对齐到 4 的倍数。而不是在结构的偏移量 2 中,它将在偏移量 4 中,添加 2 个填充字节。

现在,所有 Windows 头文件都使用选项 #pragma pack 编译,该选项告诉编译器忽略结构字段中的对齐限制。所以前一个结构实际上是:

#pragma pack(push)
typedef struct 
    WORD    bfType;      //offset 0
    DWORD   bfSize;      //offset 2
    WORD    bfReserved1; //offset 6
    WORD    bfReserved2; //offset 8
    DWORD   bfOffBits;   //offset 10
 BITMAPFILEHEADER;
#pragma pack(pop)

GCC 编译器支持#pragma pack 仅作为与 MS 编译器的兼容性,并且仅与 x86 编译器兼容。

如果你想完全可移植,你应该直接读取结构,但是将字节作为流读取并一个一个地构建值(将 2 个字节读入bfType,将 4 个字节读入bfSize,等等。 )

如果你想移植到其他 Linux,你可以使用 GCC pragma(但要注意字节序):

typedef struct __attribute__((packed)) 
    WORD    bfType;      //offset 0
    DWORD   bfSize;      //offset 2
    WORD    bfReserved1; //offset 6
    WORD    bfReserved2; //offset 8
    DWORD   bfOffBits;   //offset 10
 BITMAPFILEHEADER;

【讨论】:

我会这样做吗?:typdef uint16_t DWORD LONG 数据类型应该有多大?我的猜测是 32 位,但是在解析我的位图文件时我得到了奇怪的结果,我的 bitmapfileheader 的 reservedbits1 和 2 变量不只是像他们应该的那样包含零 @kjh:对,LONG 是一个 32 位有符号整数,即int32_t。您的新问题与数据类型无关,而是与结构的 packing 相关...请查看更新后的答案(评论太短)。 完全忽略了字节顺序部分。非常感谢,

以上是关于解析位图文件时,如何替换 WORD 和 DWORD 数据类型?的主要内容,如果未能解决你的问题,请参考以下文章

怎么把word文档转换成文本文档?

在c++ mfc中出现byte word dword 有啥实用意义

汇编中byte,word,dword的问题

如何使用 delphi 创建单色的 bmp 文件(位图)

BIT(BOOL)、BYTE、WORD、DWORD,这四个类型数据在位数上有啥区别

java如何根据word模板生成word文档