diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index d3c8ef93a1..57b73c1819 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -786,44 +786,12 @@ static void handle_small_bpp(PNGDecContext *s, AVFrame *p) } } -static int decode_frame_png(AVCodecContext *avctx, - void *data, int *got_frame, - AVPacket *avpkt) +static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, + AVFrame *p, AVPacket *avpkt) { - PNGDecContext *const s = avctx->priv_data; - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - AVFrame *p; AVDictionary *metadata = NULL; uint32_t tag, length; - int64_t sig; - int ret; - ff_thread_release_buffer(avctx, &s->last_picture); - FFSWAP(ThreadFrame, s->picture, s->last_picture); - p = s->picture.f; - - bytestream2_init(&s->gb, buf, buf_size); - - /* check signature */ - sig = bytestream2_get_be64(&s->gb); - if (sig != PNGSIG && - sig != MNGSIG) { - av_log(avctx, AV_LOG_ERROR, "Missing png signature\n"); - return AVERROR_INVALIDDATA; - } - - s->y = s->state = 0; - - /* init the zlib */ - s->zstream.zalloc = ff_png_zalloc; - s->zstream.zfree = ff_png_zfree; - s->zstream.opaque = NULL; - ret = inflateInit(&s->zstream); - if (ret != Z_OK) { - av_log(avctx, AV_LOG_ERROR, "inflateInit returned error %d\n", ret); - return AVERROR_EXTERNAL; - } for (;;) { if (bytestream2_get_bytes_left(&s->gb) <= 0) { av_log(avctx, AV_LOG_ERROR, "%d bytes left\n", bytestream2_get_bytes_left(&s->gb)); @@ -921,6 +889,53 @@ exit_loop: av_frame_set_metadata(p, metadata); metadata = NULL; + return 0; + +fail: + av_dict_free(&metadata); + ff_thread_report_progress(&s->picture, INT_MAX, 0); + return AVERROR_INVALIDDATA; +} + +static int decode_frame_png(AVCodecContext *avctx, + void *data, int *got_frame, + AVPacket *avpkt) +{ + PNGDecContext *const s = avctx->priv_data; + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + AVFrame *p; + int64_t sig; + int ret; + + ff_thread_release_buffer(avctx, &s->last_picture); + FFSWAP(ThreadFrame, s->picture, s->last_picture); + p = s->picture.f; + + bytestream2_init(&s->gb, buf, buf_size); + + /* check signature */ + sig = bytestream2_get_be64(&s->gb); + if (sig != PNGSIG && + sig != MNGSIG) { + av_log(avctx, AV_LOG_ERROR, "Missing png signature\n"); + return AVERROR_INVALIDDATA; + } + + s->y = s->state = 0; + + /* init the zlib */ + s->zstream.zalloc = ff_png_zalloc; + s->zstream.zfree = ff_png_zfree; + s->zstream.opaque = NULL; + ret = inflateInit(&s->zstream); + if (ret != Z_OK) { + av_log(avctx, AV_LOG_ERROR, "inflateInit returned error %d\n", ret); + return AVERROR_EXTERNAL; + } + + if ((ret = decode_frame_common(avctx, s, p, avpkt)) < 0) + goto the_end; if ((ret = av_frame_ref(data, s->picture.f)) < 0) return ret; @@ -932,11 +947,6 @@ the_end: inflateEnd(&s->zstream); s->crow_buf = NULL; return ret; -fail: - av_dict_free(&metadata); - ff_thread_report_progress(&s->picture, INT_MAX, 0); - ret = AVERROR_INVALIDDATA; - goto the_end; } static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src)