X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fsmacker.c;h=8345b7f8a0e29a1240526277c578b3a75a32fe61;hb=ef97d59fb315c48ac1c473597396251d5488fa13;hp=f3dec7f675e3d0b72e4f352db6482e82a32f07de;hpb=e190e453bd1e4d4b409ed3556b3a50d1087c15d7;p=ffmpeg diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c index f3dec7f675e..8345b7f8a0e 100644 --- a/libavcodec/smacker.c +++ b/libavcodec/smacker.c @@ -2,20 +2,20 @@ * Smacker decoder * Copyright (c) 2006 Konstantin Shishkov * - * 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 */ @@ -33,6 +33,7 @@ #include "avcodec.h" #include "libavutil/audioconvert.h" +#include "mathops.h" #define ALT_BITSTREAM_READER_LE #include "get_bits.h" @@ -170,7 +171,7 @@ static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx } /** - * Store large tree as Libav's vlc codes + * Store large tree as FFmpeg's vlc codes */ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int **recodes, int *last, int size) { @@ -367,7 +368,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac if(buf_size <= 769) return 0; - smk->pic.reference = 1; + smk->pic.reference = 3; smk->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; if(avctx->reget_buffer(avctx, &smk->pic) < 0){ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); @@ -521,6 +522,7 @@ static av_cold int decode_init(AVCodecContext *avctx) avctx->pix_fmt = PIX_FMT_PAL8; + avcodec_get_frame_defaults(&c->pic); /* decode huffman trees from extradata */ if(avctx->extradata_size < 16){ @@ -579,13 +581,18 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, int *data_size, HuffContext h[4]; VLC vlc[4]; int16_t *samples = data; - int8_t *samples8 = data; + uint8_t *samples8 = data; int val; int i, res; int unp_size; int bits, stereo; int pred[2] = {0, 0}; + if (buf_size <= 4) { + av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); + return AVERROR(EINVAL); + } + unp_size = AV_RL32(buf); init_get_bits(&gb, buf + 4, (buf_size - 4) * 8); @@ -601,6 +608,14 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, int *data_size, av_log(avctx, AV_LOG_ERROR, "Frame is too large to fit in buffer\n"); return -1; } + if (stereo ^ (avctx->channels != 1)) { + av_log(avctx, AV_LOG_ERROR, "channels mismatch\n"); + return AVERROR(EINVAL); + } + if (bits && avctx->sample_fmt == AV_SAMPLE_FMT_U8) { + av_log(avctx, AV_LOG_ERROR, "sample format mismatch\n"); + return AVERROR(EINVAL); + } memset(vlc, 0, sizeof(VLC) * 4); memset(h, 0, sizeof(HuffContext) * 4); @@ -642,8 +657,8 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, int *data_size, else res = 0; val |= h[3].values[res] << 8; - pred[1] += (int16_t)val; - *samples++ = pred[1]; + pred[1] += sign_extend(val, 16); + *samples++ = av_clip_int16(pred[1]); } else { if(vlc[0].table) res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); @@ -655,8 +670,8 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, int *data_size, else res = 0; val |= h[1].values[res] << 8; - pred[0] += val; - *samples++ = pred[0]; + pred[0] += sign_extend(val, 16); + *samples++ = av_clip_int16(pred[0]); } } } else { //8-bit data @@ -670,15 +685,15 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, int *data_size, res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); else res = 0; - pred[1] += (int8_t)h[1].values[res]; - *samples8++ = pred[1]; + pred[1] += sign_extend(h[1].values[res], 8); + *samples8++ = av_clip_uint8(pred[1]); } else { if(vlc[0].table) res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); else res = 0; - pred[0] += (int8_t)h[0].values[res]; - *samples8++ = pred[0]; + pred[0] += sign_extend(h[0].values[res], 8); + *samples8++ = av_clip_uint8(pred[0]); } } }