2015-03-13 85 views
1
unsigned char* Read_pixels(unsigned char *baseptr) 
{ 
    unsigned char pixelinfo[4096]; 

    pFileheader->ID1 = *baseptr++;   // save B 
    pFileheader->ID2 = *baseptr++;   // save M 

    pFileheader->FileSize = *((unsigned int*)baseptr); 
    baseptr = baseptr + 4; 

    pFileheader->Reserved = *((unsigned short*)baseptr); 
    baseptr = baseptr + 2; 

    pFileheader->Reserved2 = *((unsigned short*)baseptr); 
    baseptr = baseptr + 2; 

    pFileheader->PxOffset = *((unsigned int*)baseptr); 

} 

在這個READ BMP函數中,我收到一個指向內存中bmp文件開始的指針。 我在上面的代碼中做的是讀取fileheader並將數據存儲在fileheader結構的相應成員中。我有一個疑問,在第五行代碼中,我將一個char指針指向一個unsigned int.I,因爲FileSize值是unsigned int類型的,我的baseptr實際上是一個char指針。我做對了嗎?代碼是否正確?函數讀取bmp文件標頭

回答

0

這是正確的如果您的目標機器的字節順序與BMP標頭內的字節順序相同。在這種情況下,對於小型機器來說是正確的,這是x86 PC的情況。

如果您正在爲使用big endian的目標機器進行編譯,那麼不幸的是,除了讀取生成該單詞的四個字節並重新組合它們以形成您願意使用的32位整數。

一個可移植的方式將它使用預處理器,並具有地方做:

#ifdef BIG_ENDIAN 
    length = ((length << 24) & 0xff000000) /* Swap the 4 bytes within the word */ 
      | ((length << 8) & 0x00ff0000) 
      | ((length >> 8) & 0x0000ff00) 
      | ((length >> 24) & 0x000000ff); 
#endif 

另外,如果我是你,我會在完全匹配的BMP頭的結構使用memcpyfread找時間做它領域,遠遠超過copingy每個單獨場:)

最後最後再提醒一下,使用類型,如uint32_t代替unsigned int,這向你保證,你使用的是32位int更優雅,因爲有些機器使用16位整型你需要long得到一個32位整數。

+0

非常感謝你 – 2015-03-13 11:10:29

+0

我打算在ARM上使用它...所以它的一個32位int – 2015-03-13 11:15:12

+0

是的,並且字節順序取決於系統。大多數情況下,ARM是連接起來的,所以他們使用小端序,但並非總是如此,所以你一定要檢查一下! – Bregalad 2015-03-13 11:46:14

0

你的疑惑是有道理的。通過這種方式進行投射,假設您的輸入文件和運行的計算機具有相同的字節順序。

安全的事情是不要假設什麼而不是首先使用演員。有二進制數據轉換爲「平臺」字節序的標準函數(ntohlntohshtonl,htons),如果不需要轉換,則不執行任何操作,否則轉換。這是可行的,因爲目標操作系統的實現知道系統運行的是什麼字節序。

或者,一次只消耗一個字節的較大值,並將它們以字節順序不連續的順序連接起來。 ( 「不瞭解」 爲你的程序;輸入字節順序必須是已知的!)

例如:

pFileheader->FileSize = (unsigned int)baseptr[0] + 
    (((unsigned int)baseptr[1])<<8) + 
    (((unsigned int)baseptr[2])<<16) + 
    (((unsigned int)baseptr[3])<<24); 
    baseptr = baseptr + 4; 

pFileheader->Reserved =(unsigned int)baseptr[0] + 
    (((unsigned int)baseptr[1])<<8); 
    baseptr = baseptr + 2; 

等。如果使用了很多,寫一個函數或宏來讀取一個字或32位int。