| 
				
				
					
				
				
				 | 
			
			 | 
			@@ -800,36 +800,61 @@ static int decode_block_coeffs(VP56RangeCoder *c, DCTELEM block[16], | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                               uint8_t probs[8][3][NUM_DCT_TOKENS-1], | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                               int i, int zero_nhood, int16_t qmul[2]) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			{ | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int token, nonzero = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int offset = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    uint8_t *token_prob; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int nonzero = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    int coeff; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    for (; i < 16; i++) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        token = vp8_rac_get_tree_with_offset(c, vp8_coeff_tree, probs[vp8_coeff_band[i]][zero_nhood], offset); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    do { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        token_prob = probs[vp8_coeff_band[i]][zero_nhood]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        if (token == DCT_EOB) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            break; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        else if (token >= DCT_CAT1) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            int cat = token-DCT_CAT1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            token = vp8_rac_get_coeff(c, vp8_dct_cat_prob[cat]); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            token += 3 + (2<<cat); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        if (!vp56_rac_get_prob_branchy(c, token_prob[0]))   // DCT_EOB | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            return nonzero; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        // after the first token, the non-zero prediction context becomes | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        // based on the last decoded coeff | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        if (!token) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			skip_eob: | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        if (!vp56_rac_get_prob_branchy(c, token_prob[1])) { // DCT_0 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            zero_nhood = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            offset = 1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            continue; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        } else if (token == 1) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            token_prob = probs[vp8_coeff_band[++i]][0]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            if (i < 16) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                goto skip_eob; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            return nonzero; // invalid input; blocks should end with EOB | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        if (!vp56_rac_get_prob_branchy(c, token_prob[2])) { // DCT_1 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            coeff = 1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            zero_nhood = 1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        else | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        } else { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            zero_nhood = 2; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            if (!vp56_rac_get_prob_branchy(c, token_prob[3])) { // DCT 2,3,4 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                coeff = vp56_rac_get_prob(c, token_prob[4]); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                if (coeff) | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    coeff += vp56_rac_get_prob(c, token_prob[5]); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                coeff += 2; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            } else { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                // DCT_CAT* | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                if (!vp56_rac_get_prob_branchy(c, token_prob[6])) { | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    if (!vp56_rac_get_prob_branchy(c, token_prob[7])) { // DCT_CAT1 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                        coeff  = 5 + vp56_rac_get_prob(c, vp8_dct_cat1_prob[0]); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    } else {                                    // DCT_CAT2 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                        coeff  = 7; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                        coeff += vp56_rac_get_prob(c, vp8_dct_cat2_prob[0]) << 1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                        coeff += vp56_rac_get_prob(c, vp8_dct_cat2_prob[1]); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                } else {    // DCT_CAT3 and up | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    int a = vp56_rac_get_prob(c, token_prob[8]); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    int b = vp56_rac_get_prob(c, token_prob[9+a]); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    int cat = (a<<1) + b; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    coeff  = 3 + (8<<cat); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                    coeff += vp8_rac_get_coeff(c, vp8_dct_cat_prob[cat]); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			                } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			            } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        // todo: full [16] qmat? load into register? | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        block[zigzag_scan[i]] = (vp8_rac_get(c) ? -token : token) * qmul[!!i]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        nonzero = i+1; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        offset = 0; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        block[zigzag_scan[i]] = (vp8_rac_get(c) ? -coeff : coeff) * qmul[!!i]; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			        nonzero = ++i; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    } while (i < 16); | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			 | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			    return nonzero; | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			} | 
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
  | 
		
		
	
	
		
			
				| 
				
					
				
				
				
				 | 
			
			 | 
			
  |