void VP8PutSignedValue(VP8BitWriter* const bw, int value, int nb_bits) { if (!VP8PutBitUniform(bw, value != 0)) return; if (value < 0) { VP8PutValue(bw, ((-value) << 1) | 1, nb_bits + 1); } else { VP8PutValue(bw, value << 1, nb_bits + 1); } }
void VP8WriteProbas(VP8BitWriter* const bw, const VP8Proba* const probas) { int t, b, c, p; for (t = 0; t < NUM_TYPES; ++t) { for (b = 0; b < NUM_BANDS; ++b) { for (c = 0; c < NUM_CTX; ++c) { for (p = 0; p < NUM_PROBAS; ++p) { const uint8_t p0 = probas->coeffs_[t][b][c][p]; const int update = (p0 != VP8CoeffsProba0[t][b][c][p]); if (VP8PutBit(bw, update, VP8CoeffsUpdateProba[t][b][c][p])) { VP8PutBits(bw, p0, 8); } } } } } if (VP8PutBitUniform(bw, probas->use_skip_proba_)) { VP8PutBits(bw, probas->skip_proba_, 8); } }
static int PutCoeffs(VP8BitWriter* const bw, int ctx, const VP8Residual* res) { int n = res->first; // should be prob[VP8EncBands[n]], but it's equivalent for n=0 or 1 const uint8_t* p = res->prob[n][ctx]; if (!VP8PutBit(bw, res->last >= 0, p[0])) { return 0; } while (n < 16) { const int c = res->coeffs[n++]; const int sign = c < 0; int v = sign ? -c : c; if (!VP8PutBit(bw, v != 0, p[1])) { p = res->prob[VP8EncBands[n]][0]; continue; } if (!VP8PutBit(bw, v > 1, p[2])) { p = res->prob[VP8EncBands[n]][1]; } else { if (!VP8PutBit(bw, v > 4, p[3])) { if (VP8PutBit(bw, v != 2, p[4])) VP8PutBit(bw, v == 4, p[5]); } else if (!VP8PutBit(bw, v > 10, p[6])) { if (!VP8PutBit(bw, v > 6, p[7])) { VP8PutBit(bw, v == 6, 159); } else { VP8PutBit(bw, v >= 9, 165); VP8PutBit(bw, !(v & 1), 145); } } else { int mask; const uint8_t* tab; if (v < 3 + (8 << 1)) { // VP8Cat3 (3b) VP8PutBit(bw, 0, p[8]); VP8PutBit(bw, 0, p[9]); v -= 3 + (8 << 0); mask = 1 << 2; tab = VP8Cat3; } else if (v < 3 + (8 << 2)) { // VP8Cat4 (4b) VP8PutBit(bw, 0, p[8]); VP8PutBit(bw, 1, p[9]); v -= 3 + (8 << 1); mask = 1 << 3; tab = VP8Cat4; } else if (v < 3 + (8 << 3)) { // VP8Cat5 (5b) VP8PutBit(bw, 1, p[8]); VP8PutBit(bw, 0, p[10]); v -= 3 + (8 << 2); mask = 1 << 4; tab = VP8Cat5; } else { // VP8Cat6 (11b) VP8PutBit(bw, 1, p[8]); VP8PutBit(bw, 1, p[10]); v -= 3 + (8 << 3); mask = 1 << 10; tab = VP8Cat6; } while (mask) { VP8PutBit(bw, !!(v & mask), *tab++); mask >>= 1; } } p = res->prob[VP8EncBands[n]][2]; } VP8PutBitUniform(bw, sign); if (n == 16 || !VP8PutBit(bw, n <= res->last, p[0])) { return 1; // EOB } } return 1; }
void VP8PutValue(VP8BitWriter* const bw, int value, int nb_bits) { int mask; for (mask = 1 << (nb_bits - 1); mask; mask >>= 1) VP8PutBitUniform(bw, value & mask); }