「複雑なビットバンギング」については...ええ、それは複雑ですが、パックされたバイトとインデックスをパックされていない配列に書き留めておけば、各値の作成方法を簡単に理解できます。 ..。。
|........|........|........|........|........|
|00000000|11222222|22334444|44445566|66666677|
上記のサイクルが3回繰り返されます。
char a[24] = {
0x00,0x00, /* ................ */
0x30,0x00, /* ..@@............ */
0x78,0x00, /* .@@@@........... */
0x48,0x00, /* .@..@........... */
0xCC,0x00, /* @@..@@.......... */
0xCC,0x00, /* @@..@@.......... */
0xCC,0x00, /* @@..@@.......... */
0xFC,0x00, /* @@@@@@.......... */
0xCC,0x00, /* @@..@@.......... */
0xCC,0x00, /* @@..@@.......... */
0x00,0x00, /* ................ */
0x00,0x00 /* ................ */
};
void pack( char ap[15], const char a[24] )
{
ap[0] = a[0];
ap[1] = a[1] | (a[2] >> 2 );
ap[2] = (a[2] << 6) | (a[3] >> 2 ) | (a[4] >> 4);
ap[3] = (a[4] << 4) | (a[5] >> 4) | (a[6] >> 6);
ap[4] = (a[6] << 2) | (a[7] >> 6);
ap[5] = a[8];
ap[6] = a[9] | (a[10] >> 2 );
ap[7] = (a[10] << 6) | (a[11] >> 2 ) | (a[12] >> 4);
ap[8] = (a[12] << 4) | (a[13] >> 4) | (a[14] >> 6);
ap[9] = (a[14] << 2) | (a[15] >> 6);
ap[10] = a[16];
ap[11] = a[17] | (a[18] >> 2 );
ap[12] = (a[18] << 6) | (a[19] >> 2 ) | (a[20] >> 4);
ap[13] = (a[20] << 4) | (a[21] >> 4) | (a[22] >> 6);
ap[14] = (a[22] << 2) | (a[23] >> 6);
}
必要に応じて、上記を小さなループで実行して、間違いを犯す可能性を減らすことができます... 0から2にループし、それに応じて配列を進めます。ご存知のとおり、このようなものです(適切なポインターが必要な場合を除く)。
for( int i = 0; i < 3; i++ ) {
ap[0] = a[0];
ap[1] = a[1] | (a[2] >> 2 );
ap[2] = (a[2] << 6) | (a[3] >> 2 ) | (a[4] >> 4);
ap[3] = (a[4] << 4) | (a[5] >> 4) | (a[6] >> 6);
ap[4] = (a[6] << 2) | (a[7] >> 6);
ap += 5;
a += 8;
}
私はそれらすべてのシフトを正しくしたことを願っています=)