[Flac-dev] bitbuffer optimizations
Miroslav Lichvar
lichvarm at phoenix.inf.upol.cz
Thu Jan 30 13:37:02 PST 2003
Ok, here is a patch waiting for new CVS :). It works fine for me, but
please check it before commiting...
--
Miroslav Lichvar
-------------- next part --------------
--- src/libFLAC/bitbuffer.c.orig 2003-01-30 17:36:01.000000000 +0100
+++ src/libFLAC/bitbuffer.c 2003-01-30 21:53:18.000000000 +0100
@@ -51,6 +51,25 @@
*/
static const unsigned FLAC__BITBUFFER_DEFAULT_CAPACITY = ((65536 - 64) * 8) / FLAC__BITS_PER_BLURB; /* blurbs */
+static const unsigned char byte_to_unary_table[] = {
+ 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
#if FLAC__BITS_PER_BLURB == 8
#define FLAC__BITS_PER_BLURB_LOG2 3
#define FLAC__BYTES_PER_BLURB 1
@@ -58,6 +77,7 @@
#define FLAC__BLURB_TOP_BIT_ONE ((FLAC__byte)0x80)
#define BLURB_BIT_TO_MASK(b) (((FLAC__blurb)'\x80') >> (b))
#define CRC16_UPDATE_BLURB(bb, blurb, crc) FLAC__CRC16_UPDATE((blurb), (crc));
+#define FLAC__ALIGNED_BLURB_UNARY(blurb) (byte_to_unary_table[blurb])
#elif FLAC__BITS_PER_BLURB == 32
#define FLAC__BITS_PER_BLURB_LOG2 5
#define FLAC__BYTES_PER_BLURB 4
@@ -65,6 +85,7 @@
#define FLAC__BLURB_TOP_BIT_ONE ((FLAC__uint32)0x80000000)
#define BLURB_BIT_TO_MASK(b) (((FLAC__blurb)0x80000000) >> (b))
#define CRC16_UPDATE_BLURB(bb, blurb, crc) crc16_update_blurb((bb), (blurb));
+#define FLAC__ALIGNED_BLURB_UNARY(blurb) ((blurb) <= 0xff ? byte_to_unary_table[blurb] + 24 : ((blurb) <= 0xffff ? byte_to_unary_table[(blurb) >> 8] + 16 : ((blurb) <= 0xffffff ? byte_to_unary_table[(blurb) >> 16] + 8 : byte_to_unary_table[(blurb) >> 24])))
#else
/* ERROR, only sizes of 8 and 32 are supported */
#endif
@@ -2090,114 +2111,16 @@
if(nvals == 0)
return true;
+ cbits = bb->consumed_bits;
i = bb->consumed_blurbs;
- /*
- * We unroll the main loop to take care of partially consumed blurbs here.
- */
- if(bb->consumed_bits > 0) {
- save_blurb = blurb = buffer[i];
- cbits = bb->consumed_bits;
- blurb <<= cbits;
-
- while(1) {
- if(state == 0) {
- if(blurb) {
- for(j = 0; !(blurb & FLAC__BLURB_TOP_BIT_ONE); j++)
- blurb <<= 1;
- msbs += j;
-
- /* dispose of the unary end bit */
- blurb <<= 1;
- j++;
- cbits += j;
-
- uval = 0;
- lsbs_left = parameter;
- state++;
- if(cbits == FLAC__BITS_PER_BLURB) {
- cbits = 0;
- CRC16_UPDATE_BLURB(bb, save_blurb, bb->read_crc16);
- break;
- }
- }
- else {
- msbs += FLAC__BITS_PER_BLURB - cbits;
- cbits = 0;
- CRC16_UPDATE_BLURB(bb, save_blurb, bb->read_crc16);
- break;
- }
- }
- else {
- const unsigned available_bits = FLAC__BITS_PER_BLURB - cbits;
- if(lsbs_left >= available_bits) {
- uval <<= available_bits;
- uval |= (blurb >> cbits);
- cbits = 0;
- CRC16_UPDATE_BLURB(bb, save_blurb, bb->read_crc16);
-
- if(lsbs_left == available_bits) {
- /* compose the value */
- uval |= (msbs << parameter);
- if(uval & 1)
- vals[val_i++] = -((int)(uval >> 1)) - 1;
- else
- vals[val_i++] = (int)(uval >> 1);
- if(val_i == nvals)
- break;
-
- msbs = 0;
- state = 0;
- }
-
- lsbs_left -= available_bits;
- break;
- }
- else {
- uval <<= lsbs_left;
- uval |= (blurb >> (FLAC__BITS_PER_BLURB - lsbs_left));
- blurb <<= lsbs_left;
- cbits += lsbs_left;
-
- /* compose the value */
- uval |= (msbs << parameter);
- if(uval & 1)
- vals[val_i++] = -((int)(uval >> 1)) - 1;
- else
- vals[val_i++] = (int)(uval >> 1);
- if(val_i == nvals) {
- /* back up one if we exited the for loop because we read all nvals but the end came in the middle of a blurb */
- i--;
- break;
- }
-
- msbs = 0;
- state = 0;
- }
- }
- }
- i++;
-
- bb->consumed_blurbs = i;
- bb->consumed_bits = cbits;
- bb->total_consumed_bits = (i << FLAC__BITS_PER_BLURB_LOG2) | cbits;
- }
-
- /*
- * Now that we are blurb-aligned the logic is slightly simpler
- */
while(val_i < nvals) {
- for( ; i < bb->blurbs && val_i < nvals; i++) {
- save_blurb = blurb = buffer[i];
- cbits = 0;
+ for( ; i < bb->blurbs; i++) {
+ blurb = (save_blurb = buffer[i]) << cbits;
while(1) {
if(state == 0) {
if(blurb) {
- for(j = 0; !(blurb & FLAC__BLURB_TOP_BIT_ONE); j++)
- blurb <<= 1;
+ j = FLAC__ALIGNED_BLURB_UNARY(blurb);
msbs += j;
-
- /* dispose of the unary end bit */
- blurb <<= 1;
j++;
cbits += j;
@@ -2209,6 +2132,7 @@
CRC16_UPDATE_BLURB(bb, save_blurb, bb->read_crc16);
break;
}
+ blurb <<= j;
}
else {
msbs += FLAC__BITS_PER_BLURB - cbits;
@@ -2228,12 +2152,11 @@
if(lsbs_left == available_bits) {
/* compose the value */
uval |= (msbs << parameter);
- if(uval & 1)
- vals[val_i++] = -((int)(uval >> 1)) - 1;
- else
- vals[val_i++] = (int)(uval >> 1);
- if(val_i == nvals)
- break;
+ vals[val_i++] = (int)(uval >> 1 ^ (FLAC__int32)uval << 31 >> 31);
+ if(val_i == nvals) {
+ i++;
+ goto break2;
+ }
msbs = 0;
state = 0;
@@ -2250,15 +2173,9 @@
/* compose the value */
uval |= (msbs << parameter);
- if(uval & 1)
- vals[val_i++] = -((int)(uval >> 1)) - 1;
- else
- vals[val_i++] = (int)(uval >> 1);
- if(val_i == nvals) {
- /* back up one if we exited the for loop because we read all nvals but the end came in the middle of a blurb */
- i--;
- break;
- }
+ vals[val_i++] = (int)(uval >> 1 ^ (FLAC__int32)uval << 31 >> 31);
+ if(val_i == nvals)
+ goto break2;
msbs = 0;
state = 0;
@@ -2266,6 +2183,7 @@
}
}
}
+break2:
bb->consumed_blurbs = i;
bb->consumed_bits = cbits;
bb->total_consumed_bits = (i << FLAC__BITS_PER_BLURB_LOG2) | cbits;
More information about the Flac-dev
mailing list