X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fatrac9dec.c;h=075d610e751f60df4d3c3d4a6d7580fe591e07b3;hb=3105e970503e77f11a9d8139d38b73abe25907a9;hp=805d46f3b8089d0f4842cdf3e988532d3f190c0d;hpb=ac4b5d86222006fa71ffe5922e1a34f1422507d8;p=ffmpeg diff --git a/libavcodec/atrac9dec.c b/libavcodec/atrac9dec.c index 805d46f3b80..075d610e751 100644 --- a/libavcodec/atrac9dec.c +++ b/libavcodec/atrac9dec.c @@ -71,6 +71,8 @@ typedef struct ATRAC9BlockData { int cpe_base_channel; int is_signs[30]; + int reuseable; + } ATRAC9BlockData; typedef struct ATRAC9Context { @@ -119,10 +121,7 @@ static inline int parse_gradient(ATRAC9Context *s, ATRAC9BlockData *b, } b->grad_boundary = get_bits(gb, 4); - if (grad_range[0] >= grad_range[1] || grad_range[1] > 47) - return AVERROR_INVALIDDATA; - - if (grad_value[0] > 31 || grad_value[1] > 31) + if (grad_range[0] >= grad_range[1] || grad_range[1] > 31) return AVERROR_INVALIDDATA; if (b->grad_boundary > b->q_unit_cnt) @@ -188,7 +187,7 @@ static inline void calc_precision(ATRAC9Context *s, ATRAC9BlockData *b, for (int i = 0; i < b->q_unit_cnt; i++) { c->precision_fine[i] = 0; if (c->precision_coarse[i] > 15) { - c->precision_fine[i] = c->precision_coarse[i] - 15; + c->precision_fine[i] = FFMIN(c->precision_coarse[i], 30) - 15; c->precision_coarse[i] = 15; } } @@ -200,6 +199,8 @@ static inline int parse_band_ext(ATRAC9Context *s, ATRAC9BlockData *b, int ext_band = 0; if (b->has_band_ext) { + if (b->q_unit_cnt < 13 || b->q_unit_cnt > 20) + return AVERROR_INVALIDDATA; ext_band = at9_tab_band_ext_group[b->q_unit_cnt - 13][2]; if (stereo) { b->channel[1].band_ext = get_bits(gb, 2); @@ -222,8 +223,18 @@ static inline int parse_band_ext(ATRAC9Context *s, ATRAC9BlockData *b, b->channel[0].band_ext = get_bits(gb, 2); b->channel[0].band_ext = ext_band > 2 ? b->channel[0].band_ext : 4; - if (!get_bits(gb, 5)) + if (!get_bits(gb, 5)) { + for (int i = 0; i <= stereo; i++) { + ATRAC9ChannelData *c = &b->channel[i]; + const int count = at9_tab_band_ext_cnt[c->band_ext][ext_band]; + for (int j = 0; j < count; j++) { + int len = at9_tab_band_ext_lengths[c->band_ext][ext_band][j]; + c->band_ext_data[j] = av_clip_uintp2_c(c->band_ext_data[j], len); + } + } + return 0; + } for (int i = 0; i <= stereo; i++) { ATRAC9ChannelData *c = &b->channel[i]; @@ -241,7 +252,7 @@ static inline int read_scalefactors(ATRAC9Context *s, ATRAC9BlockData *b, ATRAC9ChannelData *c, GetBitContext *gb, int channel_idx, int first_in_pkt) { - static const int mode_map[2][4] = { { 0, 1, 2, 3 }, { 0, 2, 3, 4 } }; + static const uint8_t mode_map[2][4] = { { 0, 1, 2, 3 }, { 0, 2, 3, 4 } }; const int mode = mode_map[channel_idx][get_bits(gb, 2)]; memset(c->scalefactors, 0, sizeof(c->scalefactors)); @@ -535,9 +546,6 @@ static inline void apply_band_extension(ATRAC9Context *s, ATRAC9BlockData *b, at9_q_unit_to_coeff_idx[g_units[3]], }; - if (!b->has_band_ext || !b->has_band_ext_data) - return; - for (int ch = 0; ch <= stereo; ch++) { ATRAC9ChannelData *c = &b->channel[ch]; @@ -668,6 +676,7 @@ static int atrac9_decode_block(ATRAC9Context *s, GetBitContext *gb, if (!reuse_params) { int stereo_band, ext_band; const int min_band_count = s->samplerate_idx > 7 ? 1 : 3; + b->reuseable = 0; b->band_count = get_bits(gb, 4) + min_band_count; b->q_unit_cnt = at9_tab_band_q_unit_map[b->band_count]; @@ -699,6 +708,11 @@ static int atrac9_decode_block(ATRAC9Context *s, GetBitContext *gb, } b->band_ext_q_unit = at9_tab_band_q_unit_map[ext_band]; } + b->reuseable = 1; + } + if (!b->reuseable) { + av_log(s->avctx, AV_LOG_ERROR, "invalid block reused!\n"); + return AVERROR_INVALIDDATA; } /* Calculate bit alloc gradient */ @@ -741,7 +755,9 @@ static int atrac9_decode_block(ATRAC9Context *s, GetBitContext *gb, apply_intensity_stereo(s, b, stereo); apply_scalefactors (s, b, stereo); - apply_band_extension (s, b, stereo); + + if (b->has_band_ext && b->has_band_ext_data) + apply_band_extension (s, b, stereo); imdct: for (int i = 0; i <= stereo; i++) { @@ -833,6 +849,11 @@ static av_cold int atrac9_decode_init(AVCodecContext *avctx) av_lfg_init(&s->lfg, 0xFBADF00D); + if (avctx->block_align <= 0) { + av_log(avctx, AV_LOG_ERROR, "Invalid block align\n"); + return AVERROR_INVALIDDATA; + } + if (avctx->extradata_size != 12) { av_log(avctx, AV_LOG_ERROR, "Invalid extradata length!\n"); return AVERROR_INVALIDDATA; @@ -862,6 +883,7 @@ static av_cold int atrac9_decode_init(AVCodecContext *avctx) s->block_config = &at9_block_layout[block_config_idx]; avctx->channel_layout = s->block_config->channel_layout; + avctx->channels = av_get_channel_layout_nb_channels(avctx->channel_layout); avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; if (get_bits1(&gb)) {