X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fqpeg.c;h=3a2e56c0fb54b9b50087b65ef5c2641415db2c55;hb=00fd914d4912322212e924c15f325cebf2fde8d3;hp=bb963ed1a3d69828846c6a59139eda08dcdd5ee8;hpb=3b199d29cd597a3518136d78860e172060b9e83d;p=ffmpeg diff --git a/libavcodec/qpeg.c b/libavcodec/qpeg.c index bb963ed1a3d..3a2e56c0fb5 100644 --- a/libavcodec/qpeg.c +++ b/libavcodec/qpeg.c @@ -30,7 +30,7 @@ typedef struct QpegContext{ AVCodecContext *avctx; - AVFrame pic; + AVFrame *pic; uint8_t *refdata; uint32_t pal[256]; GetByteContext buffer; @@ -161,9 +161,9 @@ static void qpeg_decode_inter(QpegContext *qctx, uint8_t *dst, /* check motion vector */ if ((me_x + filled < 0) || (me_x + me_w + filled > width) || - (height - me_y - me_h < 0) || (height - me_y > orig_height) || + (height - me_y - me_h < 0) || (height - me_y >= orig_height) || (filled + me_w > width) || (height - me_h < 0)) - av_log(NULL, AV_LOG_ERROR, "Bogus motion vector (%i,%i), block size %ix%i at %i,%i\n", + av_log(qctx->avctx, AV_LOG_ERROR, "Bogus motion vector (%i,%i), block size %ix%i at %i,%i\n", me_x, me_y, me_w, me_h, filled, height); else { /* do motion compensation */ @@ -191,6 +191,8 @@ static void qpeg_decode_inter(QpegContext *qctx, uint8_t *dst, filled = 0; dst -= stride; height--; + if (height < 0) + break; } } } else if(code >= 0xC0) { /* copy code: 0xC0..0xDF */ @@ -202,6 +204,8 @@ static void qpeg_decode_inter(QpegContext *qctx, uint8_t *dst, filled = 0; dst -= stride; height--; + if (height < 0) + break; } } } else if(code >= 0x80) { /* skip code: 0x80..0xBF */ @@ -246,7 +250,7 @@ static int decode_frame(AVCodecContext *avctx, { uint8_t ctable[128]; QpegContext * const a = avctx->priv_data; - AVFrame * const p = &a->pic; + AVFrame * const p = a->pic; uint8_t* outdata; int delta, ret; const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); @@ -261,26 +265,26 @@ static int decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } - outdata = a->pic.data[0]; + outdata = p->data[0]; bytestream2_skip(&a->buffer, 4); bytestream2_get_buffer(&a->buffer, ctable, 128); bytestream2_skip(&a->buffer, 1); delta = bytestream2_get_byte(&a->buffer); if(delta == 0x10) { - qpeg_decode_intra(a, outdata, a->pic.linesize[0], avctx->width, avctx->height); + qpeg_decode_intra(a, outdata, p->linesize[0], avctx->width, avctx->height); } else { - qpeg_decode_inter(a, outdata, a->pic.linesize[0], avctx->width, avctx->height, delta, ctable, a->refdata); + qpeg_decode_inter(a, outdata, p->linesize[0], avctx->width, avctx->height, delta, ctable, a->refdata); } /* make the palette available on the way out */ if (pal) { - a->pic.palette_has_changed = 1; + p->palette_has_changed = 1; memcpy(a->pal, pal, AVPALETTE_SIZE); } - memcpy(a->pic.data[1], a->pal, AVPALETTE_SIZE); + memcpy(p->data[1], a->pal, AVPALETTE_SIZE); - if ((ret = av_frame_ref(data, &a->pic)) < 0) + if ((ret = av_frame_ref(data, p)) < 0) return ret; *got_frame = 1; @@ -288,36 +292,40 @@ static int decode_frame(AVCodecContext *avctx, return avpkt->size; } -static av_cold int decode_init(AVCodecContext *avctx){ +static av_cold int decode_end(AVCodecContext *avctx) +{ QpegContext * const a = avctx->priv_data; - a->avctx = avctx; - avctx->pix_fmt= AV_PIX_FMT_PAL8; - a->refdata = av_malloc(avctx->width * avctx->height); - - avcodec_get_frame_defaults(&a->pic); + av_frame_free(&a->pic); + av_free(a->refdata); return 0; } -static av_cold int decode_end(AVCodecContext *avctx){ +static av_cold int decode_init(AVCodecContext *avctx){ QpegContext * const a = avctx->priv_data; - AVFrame * const p = &a->pic; - av_frame_unref(p); + a->avctx = avctx; + avctx->pix_fmt= AV_PIX_FMT_PAL8; + a->refdata = av_malloc(avctx->width * avctx->height); + + a->pic = av_frame_alloc(); + if (!a->pic) { + decode_end(avctx); + return AVERROR(ENOMEM); + } - av_free(a->refdata); return 0; } AVCodec ff_qpeg_decoder = { .name = "qpeg", + .long_name = NULL_IF_CONFIG_SMALL("Q-team QPEG"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_QPEG, .priv_data_size = sizeof(QpegContext), .init = decode_init, .close = decode_end, .decode = decode_frame, - .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Q-team QPEG"), + .capabilities = AV_CODEC_CAP_DR1, };