2013-02-14 103 views
0

我有一個圖像數據的二進制文件,其中每個像素是正好4位。圖像數據佈局如下:二進制文件位操作

有第一個圖像是1x1,第二個圖像是2x2,第三個是4x4,等等(他們是mipmap如果你想知道)的N圖像。

給出一個指向數據緩衝區開始的指針,我想跳到最大的圖像。

現在我知道我要跳過多少個字節,但在起始處有4位這樣令人討厭的1x1圖像。無論如何,我不知道要增加一個指針。

我怎樣才能成功檢索數據沒有一切都關閉4位?

+1

這就是爲什麼通常使用填充,所以你應該。 – 2013-02-14 22:17:52

+4

將最小的圖像存儲爲一個字節(或四個,如果進入性能),並且您已完成 – 2013-02-14 22:18:53

+0

如果您可以控制圖像文件格式...只需使用[DDS](http:// en。 wikipedia.org/wiki/DirectDraw_Surface)。真的,這是存儲紋理數據的一種很好的跨平臺格式。沒有關於它們的Windows或Direct3D特有的內容。如果你絕對不能,那麼[使用KTX](http://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/),支持少得多,但它與DDS一樣全面。 – 2013-02-15 00:30:18

回答

4

假設你可以改變你的文件格式,你可以做以下任一操作:

  • 添加填充到1x1圖片
  • 商店以相反的順序圖像(有效同上,但不理想對於MIP-地圖,因爲你不一定知道你會多少圖像有)

如果你不能改變你的格式,你有這些選擇:

  • 轉換數據
  • 接受緩衝區是由半個字節偏移和與它相應的工作

你說:

我怎樣才能成功地檢索數據,而一切被關閉 由4位?

所以這意味着你需要轉換。當你以字節計算你的偏移量時,你會發現第一個包含了前一個圖像的半個字節。因此,在緊要關頭,你可以洗牌他們是這樣的:

for(i = start; i < end; i++) { 
    p[i] = (p[i] << 4) | (p[i+1] >> 4); 
} 

這是假設第一像素是位4-7,第二像素是0-3位,等等...如果它是周圍的其他方法,只是倒轉這兩個班次。

0
// this assumes pixels points to bytes(unsigned chars) 
index = ?;// your index to the pixel 

byte_t b = pixels[index/2]; 
if (index % 2) pixel = b >> 4; 
else pixel = b & 15; 

// Or you can use 
byte_t b = pixels[index >> 1]; 
if (index & 1) pixel = b >> 4; 
else pixel = b & 15; 

無論哪種方式只是計算文件中的邏輯索引。除以2會將您帶到像素所在字節的開始位置。然後只是讀取正確的一半字節。

因此,讓一個函數

byte_t GetMyPixel(unsigned char* pixels, unsigned index) { 
    byte_t b = pixels[index >> 1]; 
    byte_t pixel; 
    if (index & 1) pixel = b >> 4; 
    else pixel = b & 15; 
    return pixel; 
} 

讀出第一圖像。

Image1x1 = GetMyPixel(pixels,0); 



Image2x2_1 = GetMyPixel(pixels,1);// Top left pixel of second image 
Image2x2_2 = GetMyPixel(pixels,2);// Top Right pixel of second image 
Image2x2_3 = GetMyPixel(pixels,3);// Bottom left pixel of second image 
... etc 

所以這是一個方法去解決它。你可能需要考慮到你使用的字節順序,所以如果它看起來不對,那麼切換讀取像素的邏輯...

byte_t GetMyPixel(unsigned char* pixels, unsigned index) { 
    byte_t b = pixels[index >> 1]; 
    byte_t pixel; 
    #if OTHER_ENDIAN 
    if (index & 1) pixel = b >> 4; 
    else pixel = b & 15; 
    #else 
    if (index & 1) pixel = b & 15; 
    else pixel = b >> 4; 
    #endif 
    return pixel; 
}