From 72e33eec3a5e6d04d891e89ef0ab9d42054a6271 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Mon, 16 May 2016 22:39:03 +0200 Subject: [PATCH] avcodec/iff: add support for ANIMs with keyframes and concatenated ANIMs Signed-off-by: Paul B Mahol --- libavcodec/iff.c | 15 ++++++--------- libavformat/iff.c | 15 +++++++++++---- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/libavcodec/iff.c b/libavcodec/iff.c index 85fae1589e..9d7dce5596 100644 --- a/libavcodec/iff.c +++ b/libavcodec/iff.c @@ -63,7 +63,6 @@ typedef struct IffContext { uint8_t *video[2]; unsigned video_size; uint32_t *pal[2]; - int first; } IffContext; #define LUT8_PART(plane, v) \ @@ -422,7 +421,6 @@ static av_cold int decode_init(AVCodecContext *avctx) s->pal[1] = av_calloc(256, sizeof(*s->pal[1])); if (!s->video[0] || !s->video[1] || !s->pal[0] || !s->pal[1]) return AVERROR(ENOMEM); - s->first = 1; } if ((err = extract_header(avctx, NULL)) < 0) @@ -1322,17 +1320,11 @@ static int decode_frame(AVCodecContext *avctx, } s->init = 1; - if (s->compression <= 0xff && avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) { + if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) { if (avctx->pix_fmt == AV_PIX_FMT_PAL8) memcpy(s->pal[0], s->frame->data[1], 256 * 4); } - if (s->compression > 0xff && s->first) { - memcpy(s->video[1], s->video[0], s->video_size); - memcpy(s->pal[1], s->pal[0], 256 * 4); - s->first = 0; - } - switch (s->compression) { case 0x0: if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) { @@ -1549,6 +1541,11 @@ static int decode_frame(AVCodecContext *avctx, return unsupported(avctx); } + if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) { + memcpy(s->pal[1], s->pal[0], 256 * 4); + memcpy(s->video[1], s->video[0], s->video_size); + } + if (s->compression > 0xff) { if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) { buf = s->video[0]; diff --git a/libavformat/iff.c b/libavformat/iff.c index f3db2820a5..275710b892 100644 --- a/libavformat/iff.c +++ b/libavformat/iff.c @@ -834,20 +834,27 @@ static int iff_read_packet(AVFormatContext *s, } else if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->codecpar->codec_tag == ID_ANIM) { uint64_t data_size, orig_pos; - uint32_t chunk_id = 0; + uint32_t chunk_id, chunk_id2; while (!avio_feof(pb)) { if (avio_feof(pb)) return AVERROR_EOF; + orig_pos = avio_tell(pb); chunk_id = avio_rl32(pb); data_size = avio_rb32(pb); - orig_pos = avio_tell(pb); + chunk_id2 = avio_rl32(pb); - if (chunk_id == ID_FORM) + if (chunk_id == ID_FORM && + chunk_id2 == ID_ILBM) { + avio_skip(pb, -4); break; - else + } else if (chunk_id == ID_FORM && + chunk_id2 == ID_ANIM) { + continue; + } else { avio_skip(pb, data_size); + } } ret = av_get_packet(pb, pkt, data_size); pkt->pos = orig_pos;