X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fsvq1dec.c;h=4f8439589188dcd4c2669acec0caa102d9be2031;hb=4628443ca3534060888dd0015b229337eac13fd2;hp=3b1a275bf4d761990c9b28ebaaee159e1f7bc75f;hpb=7fbb75cc701af9bfcaac21afecdb22e5e5efd528;p=ffmpeg diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c index 3b1a275bf4d..4f843958918 100644 --- a/libavcodec/svq1dec.c +++ b/libavcodec/svq1dec.c @@ -60,6 +60,10 @@ typedef struct SVQ1Context { HpelDSPContext hdsp; GetBitContext gb; AVFrame *prev; + + uint8_t *pkt_swapped; + int pkt_swapped_allocated; + int width; int height; int frame_code; @@ -187,8 +191,8 @@ static int svq1_decode_block_intra(GetBitContext *bitbuf, uint8_t *pixels, continue; /* skip vector */ } - if (stages > 0 && level >= 4) { - av_dlog(NULL, + if ((stages > 0 && level >= 4) || stages < 0) { + ff_dlog(NULL, "Error (svq1_decode_block_intra): invalid vector: stages=%i level=%i\n", stages, level); return AVERROR_INVALIDDATA; /* invalid vector */ @@ -249,8 +253,8 @@ static int svq1_decode_block_non_intra(GetBitContext *bitbuf, uint8_t *pixels, if (stages == -1) continue; /* skip vector */ - if ((stages > 0) && (level >= 4)) { - av_dlog(NULL, + if ((stages > 0 && level >= 4) || stages < 0) { + ff_dlog(NULL, "Error (svq1_decode_block_non_intra): invalid vector: stages=%i level=%i\n", stages, level); return AVERROR_INVALIDDATA; /* invalid vector */ @@ -476,7 +480,7 @@ static int svq1_decode_delta_block(AVCodecContext *avctx, HpelDSPContext *hdsp, pitch, motion, x, y, width, height); if (result != 0) { - av_dlog(avctx, "Error in svq1_motion_inter_block %i\n", result); + ff_dlog(avctx, "Error in svq1_motion_inter_block %i\n", result); break; } result = svq1_decode_block_non_intra(bitbuf, current, pitch); @@ -487,7 +491,7 @@ static int svq1_decode_delta_block(AVCodecContext *avctx, HpelDSPContext *hdsp, pitch, motion, x, y, width, height); if (result != 0) { - av_dlog(avctx, "Error in svq1_motion_inter_4v_block %i\n", result); + ff_dlog(avctx, "Error in svq1_motion_inter_4v_block %i\n", result); break; } result = svq1_decode_block_non_intra(bitbuf, current, pitch); @@ -548,7 +552,7 @@ static int svq1_decode_frame_header(AVCodecContext *avctx, AVFrame *frame) bitbuf->size_in_bits >> 3, csum); - av_dlog(avctx, "%s checksum (%02x) for packet data\n", + ff_dlog(avctx, "%s checksum (%02x) for packet data\n", (csum == 0) ? "correct" : "incorrect", csum); } @@ -626,7 +630,25 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, /* swap some header bytes (why?) */ if (s->frame_code != 0x20) { - uint32_t *src = (uint32_t *)(buf + 4); + uint32_t *src; + + if (buf_size < 9 * 4) { + av_log(avctx, AV_LOG_ERROR, "Input packet too small\n"); + return AVERROR_INVALIDDATA; + } + + av_fast_padded_malloc(&s->pkt_swapped, + &s->pkt_swapped_allocated, + buf_size); + if (!s->pkt_swapped) + return AVERROR(ENOMEM); + + memcpy(s->pkt_swapped, buf, buf_size); + buf = s->pkt_swapped; + init_get_bits(&s->gb, buf, buf_size * 8); + skip_bits(&s->gb, 22); + + src = (uint32_t *)(s->pkt_swapped + 4); for (i = 0; i < 4; i++) src[i] = ((src[i] << 16) | (src[i] >> 16)) ^ src[7 - i]; @@ -635,7 +657,7 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, result = svq1_decode_frame_header(avctx, cur); if (result != 0) { - av_dlog(avctx, "Error in svq1_decode_frame_header %i\n", result); + ff_dlog(avctx, "Error in svq1_decode_frame_header %i\n", result); return result; } @@ -664,7 +686,7 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, width = FFALIGN(s->width, 16); height = FFALIGN(s->height, 16); } else { - if (avctx->flags & CODEC_FLAG_GRAY) + if (avctx->flags & AV_CODEC_FLAG_GRAY) break; width = FFALIGN(s->width / 4, 16); height = FFALIGN(s->height / 4, 16); @@ -706,7 +728,7 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, previous, linesize, pmv, x, y, width, height); if (result != 0) { - av_dlog(avctx, + ff_dlog(avctx, "Error in svq1_decode_delta_block %i\n", result); goto err; @@ -742,7 +764,7 @@ static av_cold int svq1_decode_init(AVCodecContext *avctx) int i; int offset = 0; - s->prev = avcodec_alloc_frame(); + s->prev = av_frame_alloc(); if (!s->prev) return AVERROR(ENOMEM); @@ -796,6 +818,7 @@ static av_cold int svq1_decode_end(AVCodecContext *avctx) SVQ1Context *s = avctx->priv_data; av_frame_free(&s->prev); + av_freep(&s->pkt_swapped); return 0; } @@ -816,7 +839,7 @@ AVCodec ff_svq1_decoder = { .init = svq1_decode_init, .close = svq1_decode_end, .decode = svq1_decode_frame, - .capabilities = CODEC_CAP_DR1, + .capabilities = AV_CODEC_CAP_DR1, .flush = svq1_flush, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV410P, AV_PIX_FMT_NONE },