static int decode_header(SnowContext *s){ int plane_index, tmp; uint8_t kstate[32]; memset(kstate, MID_STATE, sizeof(kstate)); s->keyframe= get_rac(&s->c, kstate); if(s->keyframe || s->always_reset){ ff_snow_reset_contexts(s); s->spatial_decomposition_type= s->qlog= s->qbias= s->mv_scale= s->block_max_depth= 0; } if(s->keyframe){ GET_S(s->version, tmp <= 0U) s->always_reset= get_rac(&s->c, s->header_state); s->temporal_decomposition_type= get_symbol(&s->c, s->header_state, 0); s->temporal_decomposition_count= get_symbol(&s->c, s->header_state, 0); GET_S(s->spatial_decomposition_count, 0 < tmp && tmp <= MAX_DECOMPOSITIONS) s->colorspace_type= get_symbol(&s->c, s->header_state, 0); if (s->colorspace_type == 1) { s->avctx->pix_fmt= AV_PIX_FMT_GRAY8; s->nb_planes = 1; } else if(s->colorspace_type == 0) { s->chroma_h_shift= get_symbol(&s->c, s->header_state, 0); s->chroma_v_shift= get_symbol(&s->c, s->header_state, 0); if(s->chroma_h_shift == 1 && s->chroma_v_shift==1){ s->avctx->pix_fmt= AV_PIX_FMT_YUV420P; }else if(s->chroma_h_shift == 0 && s->chroma_v_shift==0){ s->avctx->pix_fmt= AV_PIX_FMT_YUV444P; }else if(s->chroma_h_shift == 2 && s->chroma_v_shift==2){ s->avctx->pix_fmt= AV_PIX_FMT_YUV410P; } else { av_log(s, AV_LOG_ERROR, "unsupported color subsample mode %d %d\n", s->chroma_h_shift, s->chroma_v_shift); s->chroma_h_shift = s->chroma_v_shift = 1; s->avctx->pix_fmt= AV_PIX_FMT_YUV420P; return AVERROR_INVALIDDATA; } s->nb_planes = 3; } else { av_log(s, AV_LOG_ERROR, "unsupported color space\n"); s->chroma_h_shift = s->chroma_v_shift = 1; s->avctx->pix_fmt= AV_PIX_FMT_YUV420P; return AVERROR_INVALIDDATA; } s->spatial_scalability= get_rac(&s->c, s->header_state); // s->rate_scalability= get_rac(&s->c, s->header_state); GET_S(s->max_ref_frames, tmp < (unsigned)MAX_REF_FRAMES) s->max_ref_frames++; decode_qlogs(s); } if(!s->keyframe){ if(get_rac(&s->c, s->header_state)){ for(plane_index=0; plane_index<FFMIN(s->nb_planes, 2); plane_index++){ int htaps, i, sum=0; Plane *p= &s->plane[plane_index]; p->diag_mc= get_rac(&s->c, s->header_state); htaps= get_symbol(&s->c, s->header_state, 0)*2 + 2; if((unsigned)htaps >= HTAPS_MAX || htaps==0) return AVERROR_INVALIDDATA; p->htaps= htaps; for(i= htaps/2; i; i--){ p->hcoeff[i]= get_symbol(&s->c, s->header_state, 0) * (1-2*(i&1)); sum += p->hcoeff[i]; } p->hcoeff[0]= 32-sum; } s->plane[2].diag_mc= s->plane[1].diag_mc; s->plane[2].htaps = s->plane[1].htaps; memcpy(s->plane[2].hcoeff, s->plane[1].hcoeff, sizeof(s->plane[1].hcoeff)); } if(get_rac(&s->c, s->header_state)){ GET_S(s->spatial_decomposition_count, 0 < tmp && tmp <= MAX_DECOMPOSITIONS) decode_qlogs(s); } } s->spatial_decomposition_type+= get_symbol(&s->c, s->header_state, 1); if(s->spatial_decomposition_type > 1U){ av_log(s->avctx, AV_LOG_ERROR, "spatial_decomposition_type %d not supported\n", s->spatial_decomposition_type); return AVERROR_INVALIDDATA; } if(FFMIN(s->avctx-> width>>s->chroma_h_shift, s->avctx->height>>s->chroma_v_shift) >> (s->spatial_decomposition_count-1) <= 1){ av_log(s->avctx, AV_LOG_ERROR, "spatial_decomposition_count %d too large for size\n", s->spatial_decomposition_count); return AVERROR_INVALIDDATA; } if (s->avctx->width > 65536-4) { av_log(s->avctx, AV_LOG_ERROR, "Width %d is too large\n", s->avctx->width); return AVERROR_INVALIDDATA; } s->qlog += get_symbol(&s->c, s->header_state, 1); s->mv_scale += get_symbol(&s->c, s->header_state, 1); s->qbias += get_symbol(&s->c, s->header_state, 1); s->block_max_depth+= get_symbol(&s->c, s->header_state, 1); if(s->block_max_depth > 1 || s->block_max_depth < 0 || s->mv_scale > 256U){ av_log(s->avctx, AV_LOG_ERROR, "block_max_depth= %d is too large\n", s->block_max_depth); s->block_max_depth= 0; s->mv_scale = 0; return AVERROR_INVALIDDATA; } if (FFABS(s->qbias) > 127) { av_log(s->avctx, AV_LOG_ERROR, "qbias %d is too large\n", s->qbias); s->qbias = 0; return AVERROR_INVALIDDATA; } return 0; }