// Gets the next integer from the rl2 encoding. Returns EOF at end. static int rl2unpacker_getc(Rl2Unpacker *rl2) { if (rl2->b == EOF) { return EOF; } // First, count the number of zero chunks until we come to a nonzero chunk. int zero_count = 0; int bmask = (1 << rl2->n) - 1; int bv = (rl2->b & (bmask << (rl2->bi - rl2->n))); if (rl2->zero_expands) { while (bv == 0) { ++zero_count; rl2->bi -= rl2->n; if (rl2->bi <= 0) { rl2->b = rbuffer_getc(rl2->rb); rl2->bi = 8; if (rl2->b == EOF) { return EOF; } } bv = (rl2->b & (bmask << (rl2->bi - rl2->n))); } } // Infer from that the number of chunks, and hence the number of // bits, that make up the value we will extract. int num_chunks = (zero_count + 1); int bit_count = num_chunks * rl2->n; // OK, now we need to extract the next bitCount bits into a word. int result = 0; while (bit_count >= rl2->bi) { int mask = (1 << rl2->bi) - 1; int value = (rl2->b & mask); result = (result << rl2->bi) | value; bit_count -= rl2->bi; rl2->b = rbuffer_getc(rl2->rb); rl2->bi = 8; if (rl2->b == EOF) { break; } } if (bit_count > 0) { // A partial word in the middle of the byte. int bottom_count = rl2->bi - bit_count; assert(bottom_count > 0); int mask = ((1 << bit_count) - 1); int value = ((rl2->b >> bottom_count) & mask); result = (result << bit_count) | value; rl2->bi -= bit_count; }
void rl2unpacker_init(Rl2Unpacker *rl2, RBuffer *rb, int n) { // assumption: n is an integer divisor of 8. assert(n * (8 / n) == 8); rl2->rb = rb; rl2->n = n; rl2->b = rbuffer_getc(rb); rl2->bi = 8; }
static void rl2unpacker_init(Rl2Unpacker *rl2, RBuffer *rb, int n, bool zero_expands) { // assumption: n is an integer divisor of 8. assert(n * (8 / n) == 8); rl2->rb = rb; rl2->n = n; rl2->b = rbuffer_getc(rb); rl2->bi = 8; rl2->zero_expands = zero_expands; }