|
|
|
@@ -23,6 +23,7 @@ |
|
|
|
|
|
|
|
#include "libavutil/avassert.h" |
|
|
|
#include "libavutil/bprint.h" |
|
|
|
#include "libavutil/crc.h" |
|
|
|
#include "libavutil/imgutils.h" |
|
|
|
#include "libavutil/intreadwrite.h" |
|
|
|
#include "libavutil/stereo3d.h" |
|
|
|
@@ -1179,6 +1180,7 @@ static int handle_p_frame_apng(AVCodecContext *avctx, PNGDecContext *s, |
|
|
|
static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, |
|
|
|
AVFrame *p, AVPacket *avpkt) |
|
|
|
{ |
|
|
|
const AVCRC *crc_tab = av_crc_get_table(AV_CRC_32_IEEE_LE); |
|
|
|
AVDictionary **metadatap = NULL; |
|
|
|
uint32_t tag, length; |
|
|
|
int decode_next_dat = 0; |
|
|
|
@@ -1213,6 +1215,21 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, |
|
|
|
ret = AVERROR_INVALIDDATA; |
|
|
|
goto fail; |
|
|
|
} |
|
|
|
if (avctx->err_recognition & (AV_EF_CRCCHECK | AV_EF_IGNORE_ERR)) { |
|
|
|
uint32_t crc_sig = AV_RB32(s->gb.buffer + length + 4); |
|
|
|
uint32_t crc_cal = ~av_crc(crc_tab, UINT32_MAX, s->gb.buffer, length + 4); |
|
|
|
if (crc_sig ^ crc_cal) { |
|
|
|
av_log(avctx, AV_LOG_ERROR, "CRC mismatch in chunk"); |
|
|
|
if (avctx->err_recognition & AV_EF_EXPLODE) { |
|
|
|
av_log(avctx, AV_LOG_ERROR, ", quitting\n"); |
|
|
|
ret = AVERROR_INVALIDDATA; |
|
|
|
goto fail; |
|
|
|
} |
|
|
|
av_log(avctx, AV_LOG_ERROR, ", skipping\n"); |
|
|
|
bytestream2_skip(&s->gb, 4); /* tag */ |
|
|
|
goto skip_tag; |
|
|
|
} |
|
|
|
} |
|
|
|
tag = bytestream2_get_le32(&s->gb); |
|
|
|
if (avctx->debug & FF_DEBUG_STARTCODE) |
|
|
|
av_log(avctx, AV_LOG_DEBUG, "png: tag=%s length=%u\n", |
|
|
|
|