diff options
Diffstat (limited to 'libavcodec/bink.c')
-rw-r--r-- | libavcodec/bink.c | 64 |
1 files changed, 30 insertions, 34 deletions
diff --git a/libavcodec/bink.c b/libavcodec/bink.c index 059601debf..3e2bb71d85 100644 --- a/libavcodec/bink.c +++ b/libavcodec/bink.c @@ -3,20 +3,20 @@ * Copyright (c) 2009 Konstantin Shishkov * Copyright (C) 2011 Peter Ross <pross@xvid.org> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -675,6 +675,10 @@ static int read_dct_coeffs(GetBitContext *gb, int32_t block[64], const uint8_t * quant_idx = get_bits(gb, 4); } else { quant_idx = q; + if (quant_idx > 15U) { + av_log(NULL, AV_LOG_ERROR, "quant_index %d out of range\n", quant_idx); + return AVERROR_INVALIDDATA; + } } quant = quant_matrices[quant_idx]; @@ -859,7 +863,7 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, memset(dctblock, 0, sizeof(*dctblock) * 64); dctblock[0] = binkb_get_value(c, BINKB_SRC_INTRA_DC); qp = binkb_get_value(c, BINKB_SRC_INTRA_Q); - read_dct_coeffs(gb, dctblock, bink_scan, binkb_intra_quant, qp); + read_dct_coeffs(gb, dctblock, bink_scan, (const int32_t (*)[64])binkb_intra_quant, qp); c->bdsp.idct_put(dst, stride, dctblock); break; case 3: @@ -892,7 +896,7 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, memset(dctblock, 0, sizeof(*dctblock) * 64); dctblock[0] = binkb_get_value(c, BINKB_SRC_INTER_DC); qp = binkb_get_value(c, BINKB_SRC_INTER_Q); - read_dct_coeffs(gb, dctblock, bink_scan, binkb_inter_quant, qp); + read_dct_coeffs(gb, dctblock, bink_scan, (const int32_t (*)[64])binkb_inter_quant, qp); c->bdsp.idct_add(dst, stride, dctblock); break; case 5: @@ -1129,6 +1133,11 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, xoff = get_value(c, BINK_SRC_X_OFF); yoff = get_value(c, BINK_SRC_Y_OFF); ref = prev + xoff + yoff * stride; + if (ref < ref_start || ref > ref_end) { + av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n", + bx*8 + xoff, by*8 + yoff); + return -1; + } c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); memset(dctblock, 0, sizeof(*dctblock) * 64); dctblock[0] = get_value(c, BINK_SRC_INTER_DC); @@ -1224,41 +1233,28 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac static av_cold void binkb_calc_quant(void) { uint8_t inv_bink_scan[64]; - double s[64]; + static const int s[64]={ + 1073741824,1489322693,1402911301,1262586814,1073741824, 843633538, 581104888, 296244703, + 1489322693,2065749918,1945893874,1751258219,1489322693,1170153332, 806015634, 410903207, + 1402911301,1945893874,1832991949,1649649171,1402911301,1102260336, 759250125, 387062357, + 1262586814,1751258219,1649649171,1484645031,1262586814, 992008094, 683307060, 348346918, + 1073741824,1489322693,1402911301,1262586814,1073741824, 843633538, 581104888, 296244703, + 843633538,1170153332,1102260336, 992008094, 843633538, 662838617, 456571181, 232757969, + 581104888, 806015634, 759250125, 683307060, 581104888, 456571181, 314491699, 160326478, + 296244703, 410903207, 387062357, 348346918, 296244703, 232757969, 160326478, 81733730, + }; int i, j; - - for (j = 0; j < 8; j++) { - for (i = 0; i < 8; i++) { - if (j && j != 4) - if (i && i != 4) - s[j*8 + i] = cos(j * M_PI/16.0) * cos(i * M_PI/16.0) * 2.0; - else - s[j*8 + i] = cos(j * M_PI/16.0) * sqrt(2.0); - else - if (i && i != 4) - s[j*8 + i] = cos(i * M_PI/16.0) * sqrt(2.0); - else - s[j*8 + i] = 1.0; - } - } - +#define C (1LL<<30) for (i = 0; i < 64; i++) inv_bink_scan[bink_scan[i]] = i; for (j = 0; j < 16; j++) { for (i = 0; i < 64; i++) { int k = inv_bink_scan[i]; - if (s[i] == 1.0) { - binkb_intra_quant[j][k] = (1L << 12) * binkb_intra_seed[i] * - binkb_num[j]/binkb_den[j]; - binkb_inter_quant[j][k] = (1L << 12) * binkb_inter_seed[i] * - binkb_num[j]/binkb_den[j]; - } else { - binkb_intra_quant[j][k] = (1L << 12) * binkb_intra_seed[i] * s[i] * - binkb_num[j]/(double)binkb_den[j]; - binkb_inter_quant[j][k] = (1L << 12) * binkb_inter_seed[i] * s[i] * - binkb_num[j]/(double)binkb_den[j]; - } + binkb_intra_quant[j][k] = binkb_intra_seed[i] * (int64_t)s[i] * + binkb_num[j]/(binkb_den[j] * (C>>12)); + binkb_inter_quant[j][k] = binkb_inter_seed[i] * (int64_t)s[i] * + binkb_num[j]/(binkb_den[j] * (C>>12)); } } } |