Search code examples
c++bit-manipulationbinaryfilesbitwise-operators

Reading bytes from a binary file


I have got a binary file and i need to store from ( x, y ) position z amount of bytes. For example I have got this sequence of bytes :

00000000  49  49  49  49  05  00  00  00   08  00  00  00  1a  00  00  00 | y0 
00000010  39  a6  82  f8  47  8b  b8  10   78  97  f1  73  56  d9  6f  00 | y1
00000020  58  99  d5  3b  ac  7b  7b  40   b6  2e  9f  0a  69  b2  ac  a0 | y2
          ________________________________________________________________
          x0  x1  x2  x3  x4  x5  x6  x7   x8  x9  x10 x11 x12 x13 x14 x15

Every 2 merged numbers represents 1 byte ( it's taken from hexdump -C - coding is a little endian ). 49 = 1 byte, f8 is 1 byte etc ...

( x , y ) means position. For example if i put for x = 2,y = 2 i get position ( 2, 2 ) that means i start reading bytes from position y2, x2. In this case i start at byte d5 If i put z = 3 that means i want to store 3 bytes in this case those bytes are d5, 3b, ac.

I can calculate the position by a simple formula :

position = 16 * y + x  
position = 16 * 2 + 2    // i put x = 2, y = 2 to formula
position = 34    // get number 34, that means i will start storing at 35th byte in this case it's d5
binaryFile . seekg ( position )  // jump to position in a file ( itc it's 99 )
binaryFile . read ( ( char * )&dest, z )) // save z bytes

If i put z = 3 i will store 3 bytes : d5, 3b, ac.

But somtimes coefficient z , x , y are not integers:

If i put y = 2, x = 1,5 and z = 3 // ( 1,5, 2 ) That means i have to jump at byte not 99 but d5 then store 2 bytes in this case d5 , 3b and add to them half byte from byte 99 and half byte from byte ac because the starting position was x = 1,5. How could I do that ??


Solution

  • You have to extend to byte boundaries on both ends, and first read the area that you want to write. So, if you want to write two bytes, you will have to read three bytes.

    Then you will have to do appropriate bit shifting and masking to get your bits in the right places.

    For example, if you are going to write two bytes shifted ½ byte, you would start with something like this:

    unsigned char *mydata = MyDataToWrite();
    unsigned char temp[bigEnough];
    binaryFile.input(temp, 3);
    temp[0] = (temp[0] & 0xf0) | (mydata[0] >> 4);
    // more code here to put bits in temp
    binaryFile.output(temp, 3);
    

    Once you have your data in temp, write the 3 bytes back to the same location from which the were read.

    I'm not going to write the whole thing here, but I hope this gives you an idea you can work from