C++ 在C+中加载位图+;大端问题
我目前正在Visual Studio中读取位图,代码如下:C++ 在C+中加载位图+;大端问题,c++,bitmap,endianness,C++,Bitmap,Endianness,我目前正在Visual Studio中读取位图,代码如下: unsigned char* imageIO::readBMP(char* filename) { FILE* f = fopen(filename, "rb"); if (f == NULL) { printf("%s \n", "File Not Loaded"); } unsigned char info[54]; fread(info, sizeof(un
unsigned char* imageIO::readBMP(char* filename) {
FILE* f = fopen(filename, "rb");
if (f == NULL)
{
printf("%s \n", "File Not Loaded");
}
unsigned char info[54];
fread(info, sizeof(unsigned char), 54, f); //read the 54-byte header
//extract image height and width from header
imageWidth = *(int*)&info[18];
imageHeight = *(int*)&info[22];
imageBytes = 3;
size = imageWidth * imageHeight * imageBytes;
unsigned char* readData = new unsigned char[size]; //allocate 3 byte per pixel
fread(readData, sizeof(unsigned char), size, f); //read the rest of the data at once
fclose(f);
return readData;
}
然而,我试图让这段代码在PowerPC上运行,它从位图标题中提取了错误的宽度和高度。我认为这与Little Endian(常规PC)和Big Endian(PowerPC)有关
我应该如何在Big-Endian机器上读取位图
我能翻转一下小小的Endian数据吗 您可以这样做(它应该适用于大端或小端体系结构):
unsigned int getIntLE(const unsigned char*p){
#如果小丁
返回*(无符号整数*)p;
#否则
return((unsigned int)p[3]部分回答您的问题,是的,这是一个问题。您需要知道所读取数据的结构以及如何进行字节交换才能解决此问题。imageWidth=*(int*)&info[18]
违反了严格的别名,因此是未定义的行为。如果对int
有对齐限制,这样的代码可能会失败,很可能与SIGBUS
有关。我会试试看,它看起来不错!至于定义LITTLE_ENDIAN,我不确定该定义什么。我想我可以读取头文件的前几个字节和orde其中的r将决定小的或大的端点?不,该常数将为其运行的机器定义。文件格式不会改变,但构建代码的机器应该在某个地方定义此(或类似的)。如果已知数据是大的端点,只需使用ntohl()
。请参阅Arentohl()
和Windows平台上可用的朋友?我以为他们只是POSIX,但我已经很久没有在Windows上进行开发了。@MikeHarris从Windows 8.1或Server 2012开始:
unsigned int getIntLE(const unsigned char *p) {
#if LITTLE_ENDIAN
return *(unsigned int *)p;
#else
return ((unsigned int)p[3] << 24) |
((unsigned int)p[2] << 16) |
((unsigned int)p[1] << 8) |
p[0];
#endif
}
// ...
imageWidth = getIntLE(&info[18]);
imageHeight = getIntLE(&info[22]);