summaryrefslogtreecommitdiff
path: root/cesar/lib/src/bitstream.c
diff options
context:
space:
mode:
authorschodet2009-01-30 13:39:01 +0000
committerschodet2009-01-30 13:39:01 +0000
commit2ed6d9d59981ee83568ae8d41b6d8e40d73689c2 (patch)
treef5540317f8ba4dfb362d5fdea10adacc0889a052 /cesar/lib/src/bitstream.c
parent09c7b1b71368c0d58072abae22d06efe31bb88b5 (diff)
* lib/bitstream:
- add bit skipping function, closes #256. git-svn-id: svn+ssh://pessac/svn/cesar/trunk@3901 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'cesar/lib/src/bitstream.c')
-rw-r--r--cesar/lib/src/bitstream.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/cesar/lib/src/bitstream.c b/cesar/lib/src/bitstream.c
index ebd2b0cc2e..c18bd1e1b4 100644
--- a/cesar/lib/src/bitstream.c
+++ b/cesar/lib/src/bitstream.c
@@ -350,6 +350,64 @@ bitstream_write_large (bitstream_t *ctx, u64 value, uint nb_bits)
}
void
+bitstream_skip (bitstream_t *ctx, uint nb_bits)
+{
+ dbg_assert (ctx);
+ dbg_assert (ctx->direction == BITSTREAM_READ);
+ while (nb_bits)
+ {
+ /* Skip from buffer. */
+ if (nb_bits < ctx->buffer_bits)
+ {
+ /* Enough data in buffer. */
+ dbg_assert (nb_bits < 32);
+ ctx->buffer = lshrdu32 (ctx->buffer, nb_bits);
+ ctx->buffer_bits -= nb_bits;
+ nb_bits = 0;
+ }
+ else
+ {
+ /* Not enough, eat all. */
+ nb_bits -= ctx->buffer_bits;
+ ctx->buffer = 0;
+ ctx->buffer_bits = 0;
+ /* Skip from data buffer. */
+ if (nb_bits < ctx->data_bits)
+ {
+ /* Enough data, eat words. */
+ uint skip_words = nb_bits / 32;
+ uint skip_bits = nb_bits % 32;
+ nb_bits = 0;
+ ctx->data += skip_words;
+ ctx->data_bits -= skip_words * 32;
+ if (skip_bits)
+ {
+ /* Eat bits. */
+ u32 w = *ctx->data++;
+ uint read_bits = ctx->data_bits;
+ if (read_bits < 32)
+ w &= bit_mask (read_bits);
+ else
+ read_bits = 32;
+ ctx->data_bits -= read_bits;
+ ctx->buffer = lshrdu32 (w, skip_bits);
+ ctx->buffer_bits = read_bits - skip_bits;
+ }
+ }
+ else
+ {
+ /* Not enough, eat all. */
+ dbg_assert (ctx->buffer_cb);
+ nb_bits -= ctx->data_bits;
+ ctx->data = NULL;
+ ctx->data_bits = 0;
+ ctx->buffer_cb (ctx, ctx->buffer_cb_user_data);
+ }
+ }
+ }
+}
+
+void
bitstream_read_buf (bitstream_t *ctx, u8 *buf, uint size)
{
dbg_assert (ctx);