blocky/liblocky/encoder.c

42 lines
1.0 KiB
C

#include "liblocky.h"
#include <assert.h>
#include <stdio.h>
void blky_encoder_feed(blky_encoder_t* enc, uint8_t data) {
assert(enc);
assert(enc->block_num > 0);
assert(enc->feat_bits > 0);
assert(enc->feat_bits <= sizeof(enc->scrap)*8);
assert(enc->seed > 0);
if (enc->count++ == 0) enc->scrap_bits = 1;
assert(enc->scrap_bits+8 <= 32);
enc->scrap |= data << enc->scrap_bits;
enc->scrap_bits += 8;
}
bool blky_encoder_pop(blky_encoder_t* enc, uint32_t* feat, bool force) {
assert(enc);
assert(feat);
if (force) {
if (enc->scrap_bits > 0) return false;
} else {
if (enc->scrap_bits < enc->feat_bits) return false;
}
const uint32_t feat_max = 1 << enc->feat_bits;
assert(feat_max < enc->block_num);
enc->seed = blky_numeric_xorshift64(enc->seed);
*feat = blky_numeric_hop(enc->block_index, enc->scrap%feat_max, enc->seed)%enc->block_num;
enc->block_index = *feat;
enc->scrap >>= enc->feat_bits;
enc->scrap_bits -= enc->feat_bits;
return true;
}