diff options
Diffstat (limited to 'libavcodec/svq1dec.c')
-rw-r--r-- | libavcodec/svq1dec.c | 89 |
1 files changed, 46 insertions, 43 deletions
diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c index 909ace7..f65915c 100644 --- a/libavcodec/svq1dec.c +++ b/libavcodec/svq1dec.c @@ -3,25 +3,25 @@ * ported to MPlayer by Arpi <arpi@thot.banki.hu> * ported to libavcodec by Nick Kurshev <nickols_k@mail.ru> * - * Copyright (C) 2002 the xine project - * Copyright (C) 2002 the ffmpeg project + * Copyright (c) 2002 The Xine Project + * Copyright (c) 2002 The FFmpeg Project * * SVQ1 Encoder (c) 2004 Mike Melanson <melanson@pcisys.net> * - * 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 */ @@ -40,9 +40,6 @@ #include "mathops.h" #include "svq1.h" -#undef NDEBUG -#include <assert.h> - static VLC svq1_block_type; static VLC svq1_motion_component; static VLC svq1_intra_multistage[6]; @@ -114,12 +111,11 @@ static const uint8_t string_table[256] = { break; \ } \ /* divide block if next bit set */ \ - if (get_bits1(bitbuf) == 0) \ + if (!get_bits1(bitbuf)) \ break; \ /* add child nodes */ \ list[n++] = list[i]; \ - list[n++] = list[i] + \ - (((level & 1) ? pitch : 1) << (level / 2 + 1)); \ + list[n++] = list[i] + (((level & 1) ? pitch : 1) << ((level >> 1) + 1));\ } #define SVQ1_ADD_CODEBOOK() \ @@ -155,7 +151,7 @@ static const uint8_t string_table[256] = { 16 * j) << (level + 1); \ } \ mean -= stages * 128; \ - n4 = mean + (mean >> 31) << 16 | (mean & 0xFFFF); + n4 = (mean << 16) + mean; static int svq1_decode_block_intra(GetBitContext *bitbuf, uint8_t *pixels, int pitch) @@ -166,7 +162,8 @@ static int svq1_decode_block_intra(GetBitContext *bitbuf, uint8_t *pixels, const uint32_t *codebook; int entries[6]; int i, j, m, n; - int mean, stages; + int stages; + unsigned mean; unsigned x, y, width, height, level; uint32_t n1, n2, n3, n4; @@ -191,12 +188,13 @@ static int svq1_decode_block_intra(GetBitContext *bitbuf, uint8_t *pixels, continue; /* skip vector */ } - if ((stages > 0 && level >= 4) || stages < 0) { + if ((stages > 0 && level >= 4)) { av_dlog(NULL, "Error (svq1_decode_block_intra): invalid vector: stages=%i level=%i\n", stages, level); return AVERROR_INVALIDDATA; /* invalid vector */ } + av_assert0(stages >= 0); mean = get_vlc2(bitbuf, svq1_intra_mean.table, 8, 3); @@ -231,7 +229,8 @@ static int svq1_decode_block_non_intra(GetBitContext *bitbuf, uint8_t *pixels, const uint32_t *codebook; int entries[6]; int i, j, m, n; - int mean, stages; + int stages; + unsigned mean; int x, y, width, height, level; uint32_t n1, n2, n3, n4; @@ -253,12 +252,13 @@ static int svq1_decode_block_non_intra(GetBitContext *bitbuf, uint8_t *pixels, if (stages == -1) continue; /* skip vector */ - if ((stages > 0 && level >= 4) || stages < 0) { + if ((stages > 0 && level >= 4)) { av_dlog(NULL, "Error (svq1_decode_block_non_intra): invalid vector: stages=%i level=%i\n", stages, level); return AVERROR_INVALIDDATA; /* invalid vector */ } + av_assert0(stages >= 0); mean = get_vlc2(bitbuf, svq1_inter_mean.table, 9, 3) - 256; @@ -345,8 +345,7 @@ static int svq1_motion_inter_block(HpelDSPContext *hdsp, GetBitContext *bitbuf, } result = svq1_decode_motion_vector(bitbuf, &mv, pmv); - - if (result != 0) + if (result) return result; motion[0].x = @@ -389,8 +388,7 @@ static int svq1_motion_inter_4v_block(HpelDSPContext *hdsp, GetBitContext *bitbu } result = svq1_decode_motion_vector(bitbuf, &mv, pmv); - - if (result != 0) + if (result) return result; /* predict and decode motion vector (1) */ @@ -402,8 +400,7 @@ static int svq1_motion_inter_4v_block(HpelDSPContext *hdsp, GetBitContext *bitbu pmv[1] = &motion[(x / 8) + 3]; } result = svq1_decode_motion_vector(bitbuf, &motion[0], pmv); - - if (result != 0) + if (result) return result; /* predict and decode motion vector (2) */ @@ -411,8 +408,7 @@ static int svq1_motion_inter_4v_block(HpelDSPContext *hdsp, GetBitContext *bitbu pmv[2] = &motion[(x / 8) + 1]; result = svq1_decode_motion_vector(bitbuf, &motion[(x / 8) + 2], pmv); - - if (result != 0) + if (result) return result; /* predict and decode motion vector (3) */ @@ -420,8 +416,7 @@ static int svq1_motion_inter_4v_block(HpelDSPContext *hdsp, GetBitContext *bitbu pmv[3] = &motion[(x / 8) + 3]; result = svq1_decode_motion_vector(bitbuf, pmv[3], pmv); - - if (result != 0) + if (result) return result; /* form predictions */ @@ -505,7 +500,7 @@ static int svq1_decode_delta_block(AVCodecContext *avctx, HpelDSPContext *hdsp, return result; } -static void svq1_parse_string(GetBitContext *bitbuf, uint8_t *out) +static void svq1_parse_string(GetBitContext *bitbuf, uint8_t out[257]) { uint8_t seed; int i; @@ -517,6 +512,7 @@ static void svq1_parse_string(GetBitContext *bitbuf, uint8_t *out) out[i] = get_bits(bitbuf, 8) ^ seed; seed = string_table[out[i] ^ seed]; } + out[i] = 0; } static int svq1_decode_frame_header(AVCodecContext *avctx, AVFrame *frame) @@ -524,6 +520,8 @@ static int svq1_decode_frame_header(AVCodecContext *avctx, AVFrame *frame) SVQ1Context *s = avctx->priv_data; GetBitContext *bitbuf = &s->gb; int frame_size_code; + int width = s->width; + int height = s->height; skip_bits(bitbuf, 8); /* temporal_reference */ @@ -557,12 +555,12 @@ static int svq1_decode_frame_header(AVCodecContext *avctx, AVFrame *frame) } if ((s->frame_code ^ 0x10) >= 0x50) { - uint8_t msg[256]; + uint8_t msg[257]; svq1_parse_string(bitbuf, msg); av_log(avctx, AV_LOG_INFO, - "embedded message: \"%s\"\n", (char *)msg); + "embedded message:\n%s\n", ((char *)msg) + 1); } skip_bits(bitbuf, 2); @@ -574,20 +572,20 @@ static int svq1_decode_frame_header(AVCodecContext *avctx, AVFrame *frame) if (frame_size_code == 7) { /* load width, height (12 bits each) */ - s->width = get_bits(bitbuf, 12); - s->height = get_bits(bitbuf, 12); + width = get_bits(bitbuf, 12); + height = get_bits(bitbuf, 12); - if (!s->width || !s->height) + if (!width || !height) return AVERROR_INVALIDDATA; } else { /* get width, height from table */ - s->width = ff_svq1_frame_size_table[frame_size_code][0]; - s->height = ff_svq1_frame_size_table[frame_size_code][1]; + width = ff_svq1_frame_size_table[frame_size_code][0]; + height = ff_svq1_frame_size_table[frame_size_code][1]; } } /* unknown fields */ - if (get_bits1(bitbuf) == 1) { + if (get_bits1(bitbuf)) { skip_bits1(bitbuf); /* use packet checksum if (1) */ skip_bits1(bitbuf); /* component checksums after image data if (1) */ @@ -595,16 +593,18 @@ static int svq1_decode_frame_header(AVCodecContext *avctx, AVFrame *frame) return AVERROR_INVALIDDATA; } - if (get_bits1(bitbuf) == 1) { + if (get_bits1(bitbuf)) { skip_bits1(bitbuf); skip_bits(bitbuf, 4); skip_bits1(bitbuf); skip_bits(bitbuf, 2); - while (get_bits1(bitbuf) == 1) - skip_bits(bitbuf, 8); + if (skip_1stop_8data_bits(bitbuf) < 0) + return AVERROR_INVALIDDATA; } + s->width = width; + s->height = height; return 0; } @@ -620,7 +620,7 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, svq1_pmv *pmv; /* initialize bit buffer */ - init_get_bits(&s->gb, buf, buf_size * 8); + init_get_bits8(&s->gb, buf, buf_size); /* decode frame header */ s->frame_code = get_bits(&s->gb, 22); @@ -650,12 +650,14 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, src = (uint32_t *)(s->pkt_swapped + 4); + if (buf_size < 36) + return AVERROR_INVALIDDATA; + for (i = 0; i < 4; i++) src[i] = ((src[i] << 16) | (src[i] >> 16)) ^ src[7 - i]; } result = svq1_decode_frame_header(avctx, cur); - if (result != 0) { av_dlog(avctx, "Error in svq1_decode_frame_header %i\n", result); return result; @@ -700,8 +702,8 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, for (x = 0; x < width; x += 16) { result = svq1_decode_block_intra(&s->gb, ¤t[x], linesize); - if (result != 0) { - av_log(avctx, AV_LOG_INFO, + if (result) { + av_log(avctx, AV_LOG_ERROR, "Error in svq1_decode_block %i (keyframe)\n", result); goto err; @@ -819,6 +821,7 @@ static av_cold int svq1_decode_end(AVCodecContext *avctx) av_frame_free(&s->prev); av_freep(&s->pkt_swapped); + s->pkt_swapped_allocated = 0; return 0; } |