int ff_dirac_golomb_read_32bit(DiracGolombLUT *lut_ctx, const uint8_t *buf, int bytes, uint8_t *_dst, int coeffs) { int i, b, c_idx = 0; int32_t *dst = (int32_t *)_dst; DiracGolombLUT *future[4], *l = &lut_ctx[2*LUT_SIZE + buf[0]]; INIT_RESIDUE(res, 0, 0); #define APPEND_RESIDUE(N, M) \ N |= M >> (N ## _bits); \ N ## _bits += (M ## _bits) for (b = 1; b <= bytes; b++) { future[0] = &lut_ctx[buf[b]]; future[1] = future[0] + 1*LUT_SIZE; future[2] = future[0] + 2*LUT_SIZE; future[3] = future[0] + 3*LUT_SIZE; if ((c_idx + 1) > coeffs) return c_idx; /* res_bits is a hint for better branch prediction */ if (res_bits && l->sign) { int32_t coeff = 1; APPEND_RESIDUE(res, l->preamble); for (i = 0; i < (res_bits >> 1) - 1; i++) { coeff <<= 1; coeff |= (res >> (RSIZE_BITS - 2*i - 2)) & 1; } dst[c_idx++] = l->sign * (coeff - 1); res_bits = res = 0; } memcpy(&dst[c_idx], l->ready, LUT_BITS*sizeof(int32_t)); c_idx += l->ready_num; APPEND_RESIDUE(res, l->leftover); l = future[l->need_s ? 3 : !res_bits ? 2 : res_bits & 1]; } return c_idx; }