Commit 5186abdb authored by Luc Trudeau's avatar Luc Trudeau

Avoid calling get_uniform(max=1)

Calling get_uniform(max=1) results in a read_bits(n=0),
In get_uniform, the n param is renamed to max to clarify the
semantics. Asserts are added to detect calls to get_uniform()
and get_bits() that don't actually read anything.

Closes #76
parent 8eed0b67
......@@ -62,6 +62,7 @@ static void refill(GetBits *const c, const unsigned n) {
unsigned dav1d_get_bits(GetBits *const c, const unsigned n) {
assert(n <= 32 /* can go up to 57 if we change return type */);
assert(n /* can't shift state by 64 */);
if (n > c->bits_left) refill(c, n);
......@@ -78,11 +79,13 @@ int dav1d_get_sbits(GetBits *const c, const unsigned n) {
return res >> shift;
}
unsigned dav1d_get_uniform(GetBits *const c, const unsigned n) {
assert(n > 0);
const int l = ulog2(n) + 1;
assert(l > 0);
const unsigned m = (1U << l) - n;
unsigned dav1d_get_uniform(GetBits *const c, const unsigned max) {
// Output in range [0..max-1]
// max must be > 1, or else nothing is read from the bitstream
assert(max > 1);
const int l = ulog2(max) + 1;
assert(l > 1);
const unsigned m = (1U << l) - max;
const unsigned v = dav1d_get_bits(c, l - 1);
return v < m ? v : (v << 1) - m + dav1d_get_bits(c, 1);
}
......
......@@ -41,7 +41,9 @@ typedef struct GetBits {
void dav1d_init_get_bits(GetBits *c, const uint8_t *data, size_t sz);
unsigned dav1d_get_bits(GetBits *c, unsigned n);
int dav1d_get_sbits(GetBits *c, unsigned n);
unsigned dav1d_get_uniform(GetBits *c, unsigned range);
// Output in range 0..max-1
unsigned dav1d_get_uniform(GetBits *c, unsigned max);
unsigned dav1d_get_vlc(GetBits *c);
int dav1d_get_bits_subexp(GetBits *c, int ref, unsigned n);
const uint8_t *dav1d_flush_get_bits(GetBits *c);
......
......@@ -464,8 +464,10 @@ static int parse_frame_hdr(Dav1dContext *const c, GetBits *const gb,
hdr->tiling.cols = 0;
int widest_tile = 0, max_tile_area_sb = sbw * sbh;
for (int sbx = 0; sbx < sbw; hdr->tiling.cols++) {
const int tile_w = 1 + dav1d_get_uniform(gb, imin(sbw - sbx,
max_tile_width_sb));
const int tile_width_sb = imin(sbw - sbx, max_tile_width_sb);
const int tile_w = (tile_width_sb > 1) ?
1 + dav1d_get_uniform(gb, tile_width_sb) :
1;
hdr->tiling.col_start_sb[hdr->tiling.cols] = sbx;
sbx += tile_w;
widest_tile = imax(widest_tile, tile_w);
......@@ -476,8 +478,10 @@ static int parse_frame_hdr(Dav1dContext *const c, GetBits *const gb,
hdr->tiling.rows = 0;
for (int sby = 0; sby < sbh; hdr->tiling.rows++) {
const int tile_h = 1 + dav1d_get_uniform(gb, imin(sbh - sby,
max_tile_height_sb));
const int tile_height_sb = imin(sbh - sby, max_tile_height_sb);
const int tile_h = (tile_height_sb > 1) ?
1 + dav1d_get_uniform(gb, tile_height_sb) :
1;
hdr->tiling.row_start_sb[hdr->tiling.rows] = sby;
sby += tile_h;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment