Reputation: 607
Im starting with an array of 100,000 bytes where only the lower 6 bits in each byte have useful data. I need to pack that data into an array of 75,000 bytes as fast as possible, preserving the order of the data.
unsigned int Joinbits(unsigned int in) {}
Upvotes: 3
Views: 942
Reputation: 4921
// 00111111 00111111 00111111 00111111
// 000000 001111 111122 222222
void pack6(
register unsigned char o,
register unsigned char const *i,
unsigned char const *end
)
{
while(i!=end)
{
*o++ = *i << 2u | *(i+1) >> 4u; ++i;
*o++ = (*i & 0xfu) << 4u | *(i+1) >> 2u; ++i;
*o++ = (*i & 0xfcu) << 6u | *(i+1) ; i+=2;
}
}
Will fail if input length is not divisible by 4. Assumes high 2 bits of input are zero. Completely portable. Reads 4 input bytes 6 times, so 50% inefficiency on reads, however the processor cache and compiler optimiser may help. Attempting to use a variable to save the read may be counter-productive, only an actual measurement can tell.
Upvotes: 4
Reputation: 1566
This is C, I don't know C++. And is probably filled with bugs, and is by no means the fastest way, it probably isn't even fast. But I wanted to just have a go, because it seemed like a fun challenge to learn something, so please hit me with what I did wrong! :D
unsigned char unpacked[100000];
unsigned int packed[75000 / 4];
for (int i = 0; i < (100000 / 6); i += 6) {
unsigned int fourBytes = unpacked[i];
fourBytes += unpacked[i + 1] << 6;
fourBytes += unpacked[i + 2] << 12;
fourBytes += unpacked[i + 3] << 18;
fourBytes += unpacked[i + 4] << 24;
fourBytes += unpacked[i + 5] << 30;
unsigned short twoBytes = unpacked[i + 5] >> 2;
twoBytes += unpacked[i + 6] << 4
twoBytes += unpacked[i + 7] << 10;
packed[i] = fourBytes;
packed[i + 4] = twoBytes;
}
Upvotes: 0
Reputation: 9378
for(int pos=0; pos<100000; pos+=4)
{
*(int*)out = (in[0] & 0x3F) | ((in[1] & 0x3F)<<6) | ((in[2] & 0x3F)<<12) | ((in[3] & 0x3F)<<18);
in += 4;
out += 3;
}
Upvotes: 0