|
|
|
@ -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) |
|
|
|
|