2017-01-12 90 views
-1

讓我們說我有一個緩衝區,我需要得到6位。緩衝區中一個元素的四位和下一個元素的兩位。我想我知道如何從每個元素訪問正確的位,但我不知道如何組合這些位。這是一些示例代碼。如何使用位掩碼從緩衝區訪問6位

FILE * pFile; 
long lSize; 
unsigned char * buffer; 
//int16_t * buffer; 
size_t result; 

pFile = fopen ("TestFile.jpg" , "rb"); 
if (pFile==NULL) {fputs ("File error",stderr); exit (1);} 

// obtain file size: 
fseek (pFile , 0 , SEEK_END); 
lSize = ftell (pFile); 
//lSize = (ftell (pFile))/2; 
rewind (pFile); 

// allocate memory to contain the whole file: 
buffer = (unsigned char*) malloc (sizeof(unsigned char)*lSize); 
//buffer = (int16_t*) malloc (sizeof(int16_t)*lSize); 
if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);} 

// copy the file into the buffer: 
result = fread (buffer,1,lSize,pFile); 
//result = fread (buffer,2,lSize,pFile); 
if (result != lSize) {fputs ("Reading error",stderr); exit (3);} 

/* the whole file is now loaded in the memory buffer. */ 

// I think this should get the last four bits of this element (buffer[i] >> 4) & 0xF) 

// I think this should get the first two bits from the next element (buffer[i+1] & 0x3) 

if (32 == (((buffer[i] >> 4) & 0xF) & (buffer[i+1] & 0x3))){ 
/*Do something.*/ 
} 
+0

4位,你從第一個字節需要哪些,你需要從第二位開始哪兩位?在那之後,如果他們需要連接起來,他們應該在什麼順序? –

+0

感謝您的回覆。在這個例子中,第一個字節中的最後四個和第二個中的前兩個。然後爲了連接,第一個字節首先出現。所以我從緩衝區中獲得了六次連續咬傷。 – Kahless

+0

因此,對於位數爲「abcdefgh ijklmnop」的兩個字節,您需要一個包含「00efghij」位的單個字節?那是對的嗎? – Makyen

回答

2

我不知道該命令要在位結合,但也許你想是這樣的:

unsigned char lastFourBits = (buffer[i] >> 4) & 0xF;   // 0000xxxx 
unsigned char firstTwoBits = (buffer[i+1] & 0x3);   // 000000yy 
unsigned char combined = (lastFourBits << 2) | firstTwoBits; // 00xxxxyy 

或者:

unsigned char combined = (firstTwoBits << 4) | lastFourBits; // 00yyxxxx 
+0

@MikelF我傾向於同意,但我使用與他的代碼註釋中使用的相同的命名約定,以儘量減少混淆。 (由「第一位」與「最後一位」引用的位置在觀察者眼中有所不同) –

+0

對於選擇不好的單詞很抱歉。我試圖從兩個連續的字節中獲得六個連續的位。這只是讓我可以理解位移和掩飾。 – Kahless

+0

嘿所以「|」這個例子中的兩個值是什麼組合? – Kahless

1

的移位你在這裏執行(buffer[i] >> 4)實際上是失去了你想要的4位。 (buffer[i] & 0xF)將捕獲第一個字節的低位四位。對於第二個字節,您希望兩個高位(buffer[i+1] & 0xC0)捕獲這些字節。

要連接:

value = ((buffer[i] & 0x0F) << 2) + ((buffer[i+1] & 0xC0) >> 6);

一個例子:如果數據流是0xABCD,或1010 1011 1100 1101,這個等式抓住101111.

+0

非常感謝您指出。 – Kahless