avcodec/iff: add support for ANIMs with keyframes and concatenated ANIMs
Signed-off-by: Paul B Mahol <onemda@gmail.com>
This commit is contained in:
parent
8767470fb5
commit
72e33eec3a
@ -63,7 +63,6 @@ typedef struct IffContext {
|
|||||||
uint8_t *video[2];
|
uint8_t *video[2];
|
||||||
unsigned video_size;
|
unsigned video_size;
|
||||||
uint32_t *pal[2];
|
uint32_t *pal[2];
|
||||||
int first;
|
|
||||||
} IffContext;
|
} IffContext;
|
||||||
|
|
||||||
#define LUT8_PART(plane, v) \
|
#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]));
|
s->pal[1] = av_calloc(256, sizeof(*s->pal[1]));
|
||||||
if (!s->video[0] || !s->video[1] || !s->pal[0] || !s->pal[1])
|
if (!s->video[0] || !s->video[1] || !s->pal[0] || !s->pal[1])
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
s->first = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((err = extract_header(avctx, NULL)) < 0)
|
if ((err = extract_header(avctx, NULL)) < 0)
|
||||||
@ -1322,17 +1320,11 @@ static int decode_frame(AVCodecContext *avctx,
|
|||||||
}
|
}
|
||||||
s->init = 1;
|
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)
|
if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
|
||||||
memcpy(s->pal[0], s->frame->data[1], 256 * 4);
|
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) {
|
switch (s->compression) {
|
||||||
case 0x0:
|
case 0x0:
|
||||||
if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
|
if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
|
||||||
@ -1549,6 +1541,11 @@ static int decode_frame(AVCodecContext *avctx,
|
|||||||
return unsupported(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 (s->compression > 0xff) {
|
||||||
if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
|
if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
|
||||||
buf = s->video[0];
|
buf = s->video[0];
|
||||||
|
@ -834,20 +834,27 @@ static int iff_read_packet(AVFormatContext *s,
|
|||||||
} else if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
|
} else if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
|
||||||
st->codecpar->codec_tag == ID_ANIM) {
|
st->codecpar->codec_tag == ID_ANIM) {
|
||||||
uint64_t data_size, orig_pos;
|
uint64_t data_size, orig_pos;
|
||||||
uint32_t chunk_id = 0;
|
uint32_t chunk_id, chunk_id2;
|
||||||
|
|
||||||
while (!avio_feof(pb)) {
|
while (!avio_feof(pb)) {
|
||||||
if (avio_feof(pb))
|
if (avio_feof(pb))
|
||||||
return AVERROR_EOF;
|
return AVERROR_EOF;
|
||||||
|
|
||||||
|
orig_pos = avio_tell(pb);
|
||||||
chunk_id = avio_rl32(pb);
|
chunk_id = avio_rl32(pb);
|
||||||
data_size = avio_rb32(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;
|
break;
|
||||||
else
|
} else if (chunk_id == ID_FORM &&
|
||||||
|
chunk_id2 == ID_ANIM) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
avio_skip(pb, data_size);
|
avio_skip(pb, data_size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ret = av_get_packet(pb, pkt, data_size);
|
ret = av_get_packet(pb, pkt, data_size);
|
||||||
pkt->pos = orig_pos;
|
pkt->pos = orig_pos;
|
||||||
|
Loading…
Reference in New Issue
Block a user