gpt4 book ai didi

c++ - 无法在 Linux 上读取 DDS 图像 header

转载 作者:行者123 更新时间:2023-11-30 02:55:10 25 4
gpt4 key购买 nike

我使用 Nvidia nv_dds加载 DDS 图像文件以在 OpenGL 程序中使用的实用程序。它在 Windows 上工作但在 Linux (Ubuntu 12.10) 上失败。最初我认为 nv_dds 有问题,但后来发现 fread() 在 Linux (GCC 4.7) 上读取带有错误偏移量的 header 字节

这是读取 DDS 文件标记然后读取 DDS header 的 block :

// open file
FILE *fp = fopen(filename.c_str(),"rb");
if (fp == NULL) {
return false;
}
// read in file marker, make sure its a DDS file

char filecode[4];
fread(filecode, 1, 4, fp);
if (strncmp(filecode, "DDS ", 4) != 0) {
fclose(fp);
return false;
}

// read in DDS header
DDS_HEADER ddsh;
fread(&ddsh, 1,sizeof(DDS_HEADER) , fp);

当我查看 DDS_HEADER 实例的内容时,我可以看到一些实际值分配给了错误的属性,其余的都是垃圾。

然后,如果我注释掉“DDS”标记,请检查 fread():

// open file
FILE *fp = fopen(filename.c_str(), "rb");
if (fp == NULL) {
return false;
}
// read in file marker, make sure its a DDS file
/* comment out for test
char filecode[4];
fread(filecode, 1, 4, fp);
if (strncmp(filecode, "DDS ", 4) != 0) {
fclose(fp);
return false;
}
*/
// read in DDS header
DDS_HEADER ddsh;
fread(&ddsh, sizeof( DDS_HEADER ),1 , fp);//sizeof( DDS_HEADER )

然后我将图像宽度值放入 DDS_HEADER 的 imageHeight 属性中。其余属性仍然是垃圾。

当我在 Windows 机器上测试时,这一切都没有发生。fread() 在 Linux GCC 上的工作方式是否可能与在使用 MSVC 编译器的 Windows 上不同?

最佳答案

我解决了这个问题,因为没有提出有用的意见,我将自己回答这个问题。

我开始怀疑不同编译器之间数据类型大小的差异。然后我发现了这个 post .之后我发现 DDS header 的大小(用 GCC 编译)是 248,比它应该的大两倍。(MS 规范说它必须正好是 124 字节)。nv_dds dds header 使用 unsigned long 作为它的成员:

typedef struct 
{
unsigned long dwSize;
unsigned long dwFlags;
unsigned long dwHeight;
unsigned long dwWidth;
unsigned long dwPitchOrLinearSize;
unsigned long dwDepth;
unsigned long dwMipMapCount;
unsigned long dwReserved1[11];
DDS_PIXELFORMAT ddspf;
unsigned long dwCaps1;
unsigned long dwCaps2;
unsigned long dwReserved2[3];

}DDS_HEADER;

所以看起来 MSVC 编译器将 unsigned long 视为 4 个字节,而 Linux 上的 GCC 为 8 个字节。从这里开始是 header 的双倍大小。我将其全部更改为 unsigned int(也在 DDS_PIXELFORMAT header 中):

 typedef struct 
{
unsigned int dwSize;
unsigned int dwFlags;
unsigned int dwHeight;
unsigned int dwWidth;
unsigned int dwPitchOrLinearSize;
unsigned int dwDepth;
unsigned int dwMipMapCount;
unsigned int dwReserved1[11];
DDS_PIXELFORMAT ddspf;
unsigned int dwCaps1;
unsigned int dwCaps2;
unsigned int dwReserved2[3];


}DDS_HEADER;

现在一切正常!因此,与某些地方所说的相反,NVidia nv_dds 不是跨平台的(或/和交叉编译读取),应该完成此 hack 以使其在 Linux 上与 GCC 一起工作.

关于c++ - 无法在 Linux 上读取 DDS 图像 header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16645040/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com