2013-05-20 23 views
1

我使用Nvidia nv_dds實用程序來裝載DDS映像文件以在OpenGL程序中使用。它在Windows上工作,但在Linux上失敗(Ubuntu 12.10)。最初我認爲nv_dds的問題,但後來發現fread()在Linux上讀取錯誤偏移量的頭字節(GCC 4.7)無法讀取Linux上的DDS映像文件頭

這是讀取DDS文件標記,然後將DDS標題:

// 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.The休息imageHeight財產仍然是垃圾。

當我在Windows機器上測試時,所有這些都不會發生。 freq()在Linux GCC上的工作方式與在MSVC編譯器上的Windows工作方式有什麼不同?

+0

沒有人有線索?真奇怪... –

回答

1

我解決了這個問題,因爲沒有提出有用的意見,我會自己回答這個問題。

我開始懷疑不同編譯器之間數據類型大小的差異。然後我發現這個post。之後,我發現DDS頭的大小(用GCC編譯)是248,這比它應該大兩倍(MS規格說它必須是124字節).nv_dds dds頭使用無符號長度作爲其成員:

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編譯器將無符號long視爲4個字節,而Linux上的GCC佔用8個字節。從此處獲得的是標題的雙倍大小。我這一切變爲unsigned int類型(也在DDS_PIXELFORMAT頭):

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是不是跨平臺(或/!並交叉編譯閱讀),這個黑客應該完成,以使其與Linux上的GCC協同工作。

2

使用GCC longs時編譯32位時爲4字節,64位時爲8字節。使用可以使用選項-m32或-m64來顯式指定32位或64位。

0

對於ABI相關的任務,您應該總是使用類型名中定義的類型的類型,這些類型的名稱在stdint.h中定義,如int32_t/uint64_t,這樣可以在不同的平臺中編譯時節省很多問題/ little endian問題)