// With corrupt / fuzzed streams the calculation of br->value may overflow. See // b/148271109. //static VPX_NO_UNSIGNED_OVERFLOW_CHECK int GetSigned(BOOL_DECODER* br, // int value_to_sign) static int GetSigned(BOOL_DECODER br, int value_to_sign) { int split = (int)((br.range + 1) >> 1); VP8_BD_VALUE bigsplit = (VP8_BD_VALUE)split << (dboolhuff.VP8_BD_VALUE_SIZE - 8); int v; if (br.count < 0) { dboolhuff.vp8dx_bool_decoder_fill(ref br); } if (br.value < bigsplit) { br.range = (uint)split; v = value_to_sign; } else { br.range = (uint)(br.range - split); br.value = br.value - bigsplit; v = -value_to_sign; } br.range += br.range; br.value += br.value; br.count--; return(v); }
public unsafe static int vp8dx_start_decode(ref BOOL_DECODER br, in byte[] source, uint source_sz)
public static int vp8_decode_mb_tokens(VP8D_COMP dx, MACROBLOCKD x) { BOOL_DECODER bc = x.current_bc; FRAME_CONTEXT fc = dx.common.fc; //char* eobs = x->eobs; sbyte[] eobs = x.eobs; int i; int nonzeros; int eobtotal = 0; //short* qcoeff_ptr; //ProbaArray coef_probs; //int coefIndex = entropy.COEF_BANDS * entropy.PREV_COEF_CONTEXTS * entropy.ENTROPY_NODES; //ENTROPY_CONTEXT* a_ctx = ((ENTROPY_CONTEXT*)x->above_context); //ENTROPY_CONTEXT* l_ctx = ((ENTROPY_CONTEXT*)x->left_context); //ENTROPY_CONTEXT* a; //ENTROPY_CONTEXT* l; int blockSlice = entropy.COEF_BANDS * entropy.PREV_COEF_CONTEXTS * entropy.ENTROPY_NODES; fixed(byte *pCoefProbs = fc.coef_probs) { byte *coef_probs = null; fixed(sbyte *pAboveCtx = x.above_context.get().y1, pLeftContext = x.left_context.y1) { ENTROPY_CONTEXT *a_ctx = pAboveCtx; ENTROPY_CONTEXT *l_ctx = pLeftContext; ENTROPY_CONTEXT *a; ENTROPY_CONTEXT *l; int skip_dc = 0; //qcoeff_ptr = x.qcoeff[0]; fixed(short *pQcoeff = x.qcoeff) { short *qcoeff_ptr = pQcoeff; if (x.mode_info_context.get().mbmi.is_4x4 == 0) { a = a_ctx + 8; l = l_ctx + 8; //coef_probs = fc.coef_probs[1]; coef_probs = pCoefProbs + blockSlice; nonzeros = GetCoeffs(bc, coef_probs, (*a + *l), 0, qcoeff_ptr + 24 * 16); *a = *l = (sbyte)(nonzeros > 0 ? 1 : 0); eobs[24] = (sbyte)nonzeros; eobtotal += nonzeros - 16; //coef_probs = fc.coef_probs[0]; coef_probs = pCoefProbs; skip_dc = 1; } else { //coef_probs = fc.coef_probs[3]; coef_probs = pCoefProbs + 3 * blockSlice; skip_dc = 0; } for (i = 0; i < 16; ++i) { a = a_ctx + (i & 3); l = l_ctx + ((i & 0xc) >> 2); nonzeros = GetCoeffs(bc, coef_probs, (*a + *l), skip_dc, qcoeff_ptr); *a = *l = (sbyte)(nonzeros > 0 ? 1 : 0); nonzeros += skip_dc; eobs[i] = (sbyte)nonzeros; eobtotal += nonzeros; qcoeff_ptr += 16; } //coef_probs = fc.coef_probs[2]; coef_probs = pCoefProbs + 2 * blockSlice; a_ctx += 4; l_ctx += 4; for (i = 16; i < 24; ++i) { a = a_ctx + ((i > 19 ? 1 : 0) << 1) + (i & 1); l = l_ctx + ((i > 19 ? 1 : 0) << 1) + ((i & 3) > 1 ? 1 : 0); nonzeros = GetCoeffs(bc, coef_probs, (*a + *l), 0, qcoeff_ptr); *a = *l = (sbyte)(nonzeros > 0 ? 1 : 0); eobs[i] = (sbyte)nonzeros; eobtotal += nonzeros; qcoeff_ptr += 16; } } } } return(eobtotal); }
/* * Returns the position of the last non-zero coeff plus one * (and 0 if there's no coeff at all) */ /* for const-casting */ //typedef const uint8_t (*ProbaArray)[NUM_CTX] [NUM_PROBAS]; //static int GetCoeffs(BOOL_DECODER* br, ProbaArray prob, int ctx, int n, // int16_t*out) static int GetCoeffs(BOOL_DECODER br, byte *prob, int ctx, int n, short * @out) { int bigSlice = NUM_CTX * NUM_PROBAS; int smallSlice = NUM_PROBAS; //const uint8_t *p = prob[n][ctx]; byte *p = prob + n * bigSlice + ctx * smallSlice; if (VP8GetBit(ref br, p[0]) == 0) { /* first EOB is more a 'CBP' bit. */ return(0); } while (true) { ++n; if (VP8GetBit(ref br, p[1]) == 0) { //p = prob[kBands[n]][0]; p = prob + kBands[n] * bigSlice; } else { /* non zero coeff */ int v, j; if (VP8GetBit(ref br, p[2]) == 0) { //p = prob[kBands[n]][1]; p = prob + kBands[n] * bigSlice + smallSlice; v = 1; } else { if (VP8GetBit(ref br, p[3]) == 0) { if (VP8GetBit(ref br, p[4]) == 0) { v = 2; } else { v = 3 + VP8GetBit(ref br, p[5]); } } else { if (VP8GetBit(ref br, p[6]) == 0) { if (VP8GetBit(ref br, p[7]) == 0) { v = 5 + VP8GetBit(ref br, 159); } else { v = 7 + 2 * VP8GetBit(ref br, 165); v += VP8GetBit(ref br, 145); } } else { byte *tab; int bit1 = VP8GetBit(ref br, p[8]); int bit0 = VP8GetBit(ref br, p[9 + bit1]); int cat = 2 * bit1 + bit0; v = 0; fixed(byte *ptab = kCat3456[cat]) { for (tab = ptab; *tab > 0; ++tab) { v += v + VP8GetBit(ref br, *tab); } } v += 3 + (8 << cat); } } //p = prob[kBands[n]][2]; p = prob + kBands[n] * bigSlice + 2 * smallSlice; } j = kZigzag[n - 1]; @out[j] = (short)GetSigned(br, v); if (n == 16 || VP8GetBit(ref br, p[0]) == 0) { /* EOB */ return(n); } } if (n == 16) { return(16); } } }