While working on decoding some video streaming standards I have noticed a lot of instances where the bits of an Integer value are provided in anything from 2-6 bytes but separated by reserved bits, as follows:
// Specification (16 bits)
// -----------------------
// Reserved 1 bit
// Value A [6-7] 2 bit
// Reserved 2 bit
// Value A [4-5] 2 bit
// Reserved 3 bit
// Value A [0-3] 4 bit
// Reserved 2 bit
For Example, the value 185 (10111001
or 0xB9
) would be stored as follows in a two byte array:
01000110 00100100
I know this is nuts, but this is the way these guys have coded their data stream. It can be extracted using the following bit operations
int w = 0;
w |= (0x60 & data[0]) >>> 5; // extract the first 2 bits shifted to the front
w <<= 2; // bump them up 2 bits for the next section
w |= (0x06 & data[0]) >>> 1; // extract the next 2 bits shifted to the front
w <<= 4; // bump them up 4 bits for the last section
w |= (0x3C & data[0]) >>> 2; // extract the last 4 bits shifted to the front
// w now will equal 10111001 (185)
What I would like to be able to do is create a method that would accept a byte array of undetermined length and an Int representing a mask of the bits that constitue the value we are trying to extract derived from the specification provided. Something like this
public static void testMethod() {
byte[] data = new byte[] {0x46, 0x24}; // 01000110 00100100
int mask = 0x663C; // 01100110 00111100
int x = readIntFromMaskedBytes(data, mask);
}
public static int readIntFromMaskedBytes(byte[] data, int mask) {
int result = 0;
// use the mask to extract the marks bits from each
// byte and shift them appropriately to form an int
return result;
}
I have completed the project I was working on using the original "manual" approach, but I am not satisfied that it is as clean as it could be due to the sheer number of these occurrences and their complexity. I would love to come up with a more generic method that could accomplish the same thing.
Unfortunately I'm still a newbie when it comes to this complexity of bit shifting and I was hoping someone could provide some advice or suggestions on how best to accomplish this.
Xela
Note - Excuse any syntax errors in the pseudo-code above it is only design to serve as an explanation of the use case.