@ -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 ;
}