diff options
Diffstat (limited to 'libavcodec/huffyuvdec.c')
-rw-r--r-- | libavcodec/huffyuvdec.c | 105 |
1 files changed, 66 insertions, 39 deletions
diff --git a/libavcodec/huffyuvdec.c b/libavcodec/huffyuvdec.c index 7a58ba4688..e5a9e3bf81 100644 --- a/libavcodec/huffyuvdec.c +++ b/libavcodec/huffyuvdec.c @@ -6,20 +6,20 @@ * see http://www.pcisys.net/~melanson/codecs/huffyuv.txt for a description of * the algorithm used * - * 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 */ @@ -37,14 +37,16 @@ static const unsigned char classic_shift_luma[classic_shift_luma_table_size + FF_INPUT_BUFFER_PADDING_SIZE] = { 34,36,35,69,135,232,9,16,10,24,11,23,12,16,13,10,14,8,15,8, 16,8,17,20,16,10,207,206,205,236,11,8,10,21,9,23,8,8,199,70, - 69,68, 0 + 69,68, 0, + 0,0,0,0,0,0,0,0, }; #define classic_shift_chroma_table_size 59 static const unsigned char classic_shift_chroma[classic_shift_chroma_table_size + FF_INPUT_BUFFER_PADDING_SIZE] = { 66,36,37,38,39,40,41,75,76,77,110,239,144,81,82,83,84,85,118,183, 56,57,88,89,56,89,154,57,58,57,26,141,57,56,58,57,58,57,184,119, - 214,245,116,83,82,49,80,79,78,77,44,75,41,40,39,38,37,36,34, 0 + 214,245,116,83,82,49,80,79,78,77,44,75,41,40,39,38,37,36,34, 0, + 0,0,0,0,0,0,0,0, }; static const unsigned char classic_add_luma[256] = { @@ -104,23 +106,26 @@ static int read_len_table(uint8_t *dst, GetBitContext *gb) return 0; } -static void generate_joint_tables(HYuvContext *s) +static int generate_joint_tables(HYuvContext *s) { uint16_t symbols[1 << VLC_BITS]; uint16_t bits[1 << VLC_BITS]; uint8_t len[1 << VLC_BITS]; + int ret; + if (s->bitstream_bpp < 24) { int p, i, y, u; for (p = 0; p < 3; p++) { for (i = y = 0; y < 256; y++) { int len0 = s->len[0][y]; int limit = VLC_BITS - len0; - if(limit <= 0) + if(limit <= 0 || !len0) continue; for (u = 0; u < 256; u++) { int len1 = s->len[p][u]; - if (len1 > limit) + if (len1 > limit || !len1) continue; + av_assert0(i < (1 << VLC_BITS)); len[i] = len0 + len1; bits[i] = (s->bits[0][y] << len1) + s->bits[p][u]; symbols[i] = (y << 8) + u; @@ -129,8 +134,9 @@ static void generate_joint_tables(HYuvContext *s) } } ff_free_vlc(&s->vlc[3 + p]); - ff_init_vlc_sparse(&s->vlc[3 + p], VLC_BITS, i, len, 1, 1, - bits, 2, 2, symbols, 2, 2, 0); + if ((ret = ff_init_vlc_sparse(&s->vlc[3 + p], VLC_BITS, i, len, 1, 1, + bits, 2, 2, symbols, 2, 2, 0)) < 0) + return ret; } } else { uint8_t (*map)[4] = (uint8_t(*)[4])s->pix_bgr_map; @@ -143,18 +149,19 @@ static void generate_joint_tables(HYuvContext *s) for (i = 0, g = -16; g < 16; g++) { int len0 = s->len[p0][g & 255]; int limit0 = VLC_BITS - len0; - if (limit0 < 2) + if (limit0 < 2 || !len0) continue; for (b = -16; b < 16; b++) { int len1 = s->len[p1][b & 255]; int limit1 = limit0 - len1; - if (limit1 < 1) + if (limit1 < 1 || !len1) continue; code = (s->bits[p0][g & 255] << len1) + s->bits[p1][b & 255]; for (r = -16; r < 16; r++) { int len2 = s->len[2][r & 255]; - if (len2 > limit1) + if (len2 > limit1 || !len2) continue; + av_assert0(i < (1 << VLC_BITS)); len[i] = len0 + len1 + len2; bits[i] = (code << len2) + s->bits[2][r & 255]; if (s->decorrelate) { @@ -171,14 +178,17 @@ static void generate_joint_tables(HYuvContext *s) } } ff_free_vlc(&s->vlc[3]); - init_vlc(&s->vlc[3], VLC_BITS, i, len, 1, 1, bits, 2, 2, 0); + if ((ret = init_vlc(&s->vlc[3], VLC_BITS, i, len, 1, 1, bits, 2, 2, 0)) < 0) + return ret; } + return 0; } static int read_huffman_tables(HYuvContext *s, const uint8_t *src, int length) { GetBitContext gb; int i; + int ret; init_get_bits(&gb, src, length * 8); @@ -189,11 +199,13 @@ static int read_huffman_tables(HYuvContext *s, const uint8_t *src, int length) return -1; } ff_free_vlc(&s->vlc[i]); - init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, - s->bits[i], 4, 4, 0); + if ((ret = init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, + s->bits[i], 4, 4, 0)) < 0) + return ret; } - generate_joint_tables(s); + if ((ret = generate_joint_tables(s)) < 0) + return ret; return (get_bits_count(&gb) + 7) / 8; } @@ -202,6 +214,7 @@ static int read_old_huffman_tables(HYuvContext *s) { GetBitContext gb; int i; + int ret; init_get_bits(&gb, classic_shift_luma, classic_shift_luma_table_size * 8); @@ -225,11 +238,13 @@ static int read_old_huffman_tables(HYuvContext *s) for (i = 0; i < 3; i++) { ff_free_vlc(&s->vlc[i]); - init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, - s->bits[i], 4, 4, 0); + if ((ret = init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, + s->bits[i], 4, 4, 0)) < 0) + return ret; } - generate_joint_tables(s); + if ((ret = generate_joint_tables(s)) < 0) + return ret; return 0; } @@ -241,6 +256,7 @@ static av_cold int decode_init(AVCodecContext *avctx) ff_huffyuv_common_init(avctx); memset(s->vlc, 0, 3 * sizeof(VLC)); + avcodec_get_frame_defaults(&s->picture); s->interlaced = s->height > 288; s->bgr32 = 1; @@ -272,7 +288,7 @@ static av_cold int decode_init(AVCodecContext *avctx) if ( read_huffman_tables(s, ((uint8_t*)avctx->extradata) + 4, avctx->extradata_size - 4) < 0) - return -1; + return AVERROR_INVALIDDATA; }else{ switch (avctx->bits_per_coded_sample & 7) { case 1: @@ -300,7 +316,7 @@ static av_cold int decode_init(AVCodecContext *avctx) s->context = 0; if (read_old_huffman_tables(s) < 0) - return -1; + return AVERROR_INVALIDDATA; } switch (s->bitstream_bpp) { @@ -326,7 +342,18 @@ static av_cold int decode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } - ff_huffyuv_alloc_temp(s); + if ((avctx->pix_fmt == AV_PIX_FMT_YUV422P || avctx->pix_fmt == AV_PIX_FMT_YUV420P) && avctx->width & 1) { + av_log(avctx, AV_LOG_ERROR, "width must be even for this colorspace\n"); + return AVERROR_INVALIDDATA; + } + if (s->predictor == MEDIAN && avctx->pix_fmt == AV_PIX_FMT_YUV422P && avctx->width%4) { + av_log(avctx, AV_LOG_ERROR, "width must be a multiple of 4 this colorspace and predictor\n"); + return AVERROR_INVALIDDATA; + } + if (ff_huffyuv_alloc_temp(s)) { + ff_huffyuv_common_end(s); + return AVERROR(ENOMEM); + } return 0; } @@ -336,7 +363,10 @@ static av_cold int decode_init_thread_copy(AVCodecContext *avctx) HYuvContext *s = avctx->priv_data; int i; - ff_huffyuv_alloc_temp(s); + if (ff_huffyuv_alloc_temp(s)) { + ff_huffyuv_common_end(s); + return AVERROR(ENOMEM); + } for (i = 0; i < 6; i++) s->vlc[i].table = NULL; @@ -344,10 +374,10 @@ static av_cold int decode_init_thread_copy(AVCodecContext *avctx) if (s->version == 2) { if (read_huffman_tables(s, ((uint8_t*)avctx->extradata) + 4, avctx->extradata_size) < 0) - return -1; + return AVERROR_INVALIDDATA; } else { if (read_old_huffman_tables(s) < 0) - return -1; + return AVERROR_INVALIDDATA; } return 0; @@ -482,31 +512,28 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, int fake_ystride, fake_ustride, fake_vstride; ThreadFrame frame = { .f = data }; AVFrame * const p = data; - int table_size = 0; + int table_size = 0, ret; - av_fast_malloc(&s->bitstream_buffer, + av_fast_padded_malloc(&s->bitstream_buffer, &s->bitstream_buffer_size, - buf_size + FF_INPUT_BUFFER_PADDING_SIZE); + buf_size); if (!s->bitstream_buffer) return AVERROR(ENOMEM); - memset(s->bitstream_buffer + buf_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); s->dsp.bswap_buf((uint32_t*)s->bitstream_buffer, (const uint32_t*)buf, buf_size / 4); - if (ff_thread_get_buffer(avctx, &frame, 0) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } + if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) + return ret; if (s->context) { table_size = read_huffman_tables(s, s->bitstream_buffer, buf_size); if (table_size < 0) - return -1; + return AVERROR_INVALIDDATA; } if ((unsigned)(buf_size-table_size) >= INT_MAX / 8) - return -1; + return AVERROR_INVALIDDATA; init_get_bits(&s->gb, s->bitstream_buffer+table_size, (buf_size-table_size) * 8); @@ -530,7 +557,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, av_log(avctx, AV_LOG_ERROR, "YUY2 output is not implemented yet\n"); - return -1; + return AVERROR_PATCHWELCOME; } else { leftv = p->data[2][0] = get_bits(&s->gb, 8); @@ -712,7 +739,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, }else{ av_log(avctx, AV_LOG_ERROR, "BGR24 output is not implemented yet\n"); - return -1; + return AVERROR_PATCHWELCOME; } } emms_c(); |