add FLAC__bitbuffer_read_rice_signed_block()
authorJosh Coalson <jcoalson@users.sourceforce.net>
Thu, 25 Apr 2002 05:21:09 +0000 (05:21 +0000)
committerJosh Coalson <jcoalson@users.sourceforce.net>
Thu, 25 Apr 2002 05:21:09 +0000 (05:21 +0000)
src/libFLAC/bitbuffer.c
src/libFLAC/include/private/bitbuffer.h
src/libFLAC/stream_decoder.c

index b08496130ee06e8d7c89a89606e21920c579b5d5..d31a482924c470ad32abf481b38a7c2a2db49a23 100644 (file)
@@ -1941,6 +1941,214 @@ FLAC__bool FLAC__bitbuffer_read_rice_signed(FLAC__BitBuffer *bb, int *val, unsig
        return true;
 }
 
+FLAC__bool FLAC__bitbuffer_read_rice_signed_block(FLAC__BitBuffer *bb, int vals[], unsigned nvals, unsigned parameter, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data)
+{
+       const FLAC__blurb *buffer = bb->buffer;
+
+       unsigned i, j, uval, val_i = 0;
+       unsigned msbs = 0, lsbs_left;
+       FLAC__blurb blurb, save_blurb, cbits;
+       unsigned state = 0; /* 0 = getting unary MSBs, 1 = getting binary LSBs */
+
+       FLAC__ASSERT(bb != 0);
+       FLAC__ASSERT(bb->buffer != 0);
+       FLAC__ASSERT(parameter <= 31);
+
+       if(nvals == 0)
+               return true;
+
+       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;
+                       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;
+                                       }
+                               }
+                       }
+               }
+               bb->consumed_blurbs = i;
+               bb->consumed_bits = cbits;
+               bb->total_consumed_bits = (i << FLAC__BITS_PER_BLURB_LOG2) | cbits;
+               if(val_i < nvals) {
+                       if(!bitbuffer_read_from_client_(bb, read_callback, client_data))
+                               return false;
+                       /* these must be zero because we can only get here if we got to the end of the buffer */
+                       FLAC__ASSERT(bb->consumed_blurbs == 0);
+                       FLAC__ASSERT(bb->consumed_bits == 0);
+                       i = 0;
+               }
+       }
+
+       return true;
+}
+
 #if 0 /* UNUSED */
 FLAC__bool FLAC__bitbuffer_read_golomb_signed(FLAC__BitBuffer *bb, int *val, unsigned parameter, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data)
 {
@@ -2147,6 +2355,7 @@ void FLAC__bitbuffer_dump(const FLAC__BitBuffer *bb, FILE *out)
        }
        else {
                fprintf(out, "bitbuffer: capacity=%u blurbs=%u bits=%u total_bits=%u consumed: blurbs=%u, bits=%u, total_bits=%u\n", bb->capacity, bb->blurbs, bb->bits, bb->total_bits, bb->consumed_blurbs, bb->consumed_bits, bb->total_consumed_bits);
+return;//@@@
                for(i = 0; i < bb->blurbs; i++) {
                        fprintf(out, "%08X: ", i);
                        for(j = 0; j < FLAC__BITS_PER_BLURB; j++)
index 43ead8ee4748aa118a47d87e8dffb4555ee10d52..b709378c2db5138235799013b70882c479089340 100644 (file)
@@ -126,6 +126,7 @@ FLAC__bool FLAC__bitbuffer_read_unary_unsigned(FLAC__BitBuffer *bb, unsigned *va
 FLAC__bool FLAC__bitbuffer_read_symmetric_rice_signed(FLAC__BitBuffer *bb, int *val, unsigned parameter, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data);
 #endif
 FLAC__bool FLAC__bitbuffer_read_rice_signed(FLAC__BitBuffer *bb, int *val, unsigned parameter, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data);
+FLAC__bool FLAC__bitbuffer_read_rice_signed_block(FLAC__BitBuffer *bb, int vals[], unsigned nvals, unsigned parameter, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data);
 #if 0 /* UNUSED */
 FLAC__bool FLAC__bitbuffer_read_golomb_signed(FLAC__BitBuffer *bb, int *val, unsigned parameter, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data);
 FLAC__bool FLAC__bitbuffer_read_golomb_unsigned(FLAC__BitBuffer *bb, unsigned *val, unsigned parameter, FLAC__bool (*read_callback)(FLAC__byte buffer[], unsigned *bytes, void *client_data), void *client_data);
index abe8613b4ab565cfe38b4ff2d9a33e975c130095..423845bb3bef1563f7654e3364594e7ede618e38 100644 (file)
@@ -1492,16 +1492,18 @@ FLAC__bool stream_decoder_read_residual_partitioned_rice_(FLAC__StreamDecoder *d
                        return false; /* the read_callback_ sets the state for us */
                partitioned_rice->parameters[partition] = rice_parameter;
                if(rice_parameter < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) {
-                       for(u = (partition_order == 0 || partition > 0)? 0 : predictor_order; u < partition_samples; u++, sample++) {
 #ifdef FLAC__SYMMETRIC_RICE
+                       for(u = (partition_order == 0 || partition > 0)? 0 : predictor_order; u < partition_samples; u++, sample++) {
                                if(!FLAC__bitbuffer_read_symmetric_rice_signed(decoder->private_->input, &i, rice_parameter, read_callback_, decoder))
                                        return false; /* the read_callback_ sets the state for us */
-#else
-                               if(!FLAC__bitbuffer_read_rice_signed(decoder->private_->input, &i, rice_parameter, read_callback_, decoder))
-                                       return false; /* the read_callback_ sets the state for us */
-#endif
                                residual[sample] = i;
                        }
+#else
+                       u = (partition_order == 0 || partition > 0)? partition_samples : partition_samples - predictor_order;
+                       if(!FLAC__bitbuffer_read_rice_signed_block(decoder->private_->input, residual + sample, u, rice_parameter, read_callback_, decoder))
+                               return false; /* the read_callback_ sets the state for us */
+                       sample += u;
+#endif
                }
                else {
                        if(!FLAC__bitbuffer_read_raw_uint32(decoder->private_->input, &rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN, read_callback_, decoder))