|
|
|
@@ -151,17 +151,17 @@ static int apng_read_header(AVFormatContext *s) |
|
|
|
uint32_t len, tag; |
|
|
|
AVStream *st; |
|
|
|
int acTL_found = 0; |
|
|
|
int64_t ret = AVERROR_INVALIDDATA; |
|
|
|
int64_t ret; |
|
|
|
|
|
|
|
/* verify PNGSIG */ |
|
|
|
if (avio_rb64(pb) != PNGSIG) |
|
|
|
return ret; |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
|
|
|
/* parse IHDR (must be first chunk) */ |
|
|
|
len = avio_rb32(pb); |
|
|
|
tag = avio_rl32(pb); |
|
|
|
if (len != 13 || tag != MKTAG('I', 'H', 'D', 'R')) |
|
|
|
return ret; |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
|
|
|
st = avformat_new_stream(s, NULL); |
|
|
|
if (!st) |
|
|
|
@@ -193,11 +193,9 @@ static int apng_read_header(AVFormatContext *s) |
|
|
|
int64_t size = avio_size(pb); |
|
|
|
int64_t offset = avio_tell(pb); |
|
|
|
if (size < 0) { |
|
|
|
ret = size; |
|
|
|
goto fail; |
|
|
|
return size; |
|
|
|
} else if (offset < 0) { |
|
|
|
ret = offset; |
|
|
|
goto fail; |
|
|
|
return offset; |
|
|
|
} else if ((ret = ffio_ensure_seekback(pb, size - offset)) < 0) { |
|
|
|
av_log(s, AV_LOG_WARNING, "Could not ensure seekback, will not loop\n"); |
|
|
|
ctx->num_play = 1; |
|
|
|
@@ -205,20 +203,18 @@ static int apng_read_header(AVFormatContext *s) |
|
|
|
} |
|
|
|
if ((ctx->num_play == 1 || !acTL_found) && |
|
|
|
((ret = ffio_ensure_seekback(pb, 4 /* len */ + 4 /* tag */)) < 0)) |
|
|
|
goto fail; |
|
|
|
return ret; |
|
|
|
|
|
|
|
len = avio_rb32(pb); |
|
|
|
if (len > INT_MAX - 12) { |
|
|
|
ret = AVERROR_INVALIDDATA; |
|
|
|
goto fail; |
|
|
|
} |
|
|
|
if (len > INT_MAX - 12) |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
|
|
|
tag = avio_rl32(pb); |
|
|
|
switch (tag) { |
|
|
|
case MKTAG('a', 'c', 'T', 'L'): |
|
|
|
if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 || |
|
|
|
(ret = append_extradata(st->codecpar, pb, len + 12)) < 0) |
|
|
|
goto fail; |
|
|
|
return ret; |
|
|
|
acTL_found = 1; |
|
|
|
ctx->num_frames = AV_RB32(st->codecpar->extradata + ret + 8); |
|
|
|
ctx->num_play = AV_RB32(st->codecpar->extradata + ret + 12); |
|
|
|
@@ -227,21 +223,17 @@ static int apng_read_header(AVFormatContext *s) |
|
|
|
break; |
|
|
|
case MKTAG('f', 'c', 'T', 'L'): |
|
|
|
if (!acTL_found || len != 26) { |
|
|
|
ret = AVERROR_INVALIDDATA; |
|
|
|
goto fail; |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
} |
|
|
|
if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0) |
|
|
|
goto fail; |
|
|
|
return ret; |
|
|
|
return 0; |
|
|
|
default: |
|
|
|
if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 || |
|
|
|
(ret = append_extradata(st->codecpar, pb, len + 12)) < 0) |
|
|
|
goto fail; |
|
|
|
return ret; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
fail: |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|
static int decode_fctl_chunk(AVFormatContext *s, APNGDemuxContext *ctx, AVPacket *pkt) |
|
|
|
|