diff options
Diffstat (limited to 'ffmpeg/libavformat/anm.c')
| -rw-r--r-- | ffmpeg/libavformat/anm.c | 229 |
1 files changed, 0 insertions, 229 deletions
diff --git a/ffmpeg/libavformat/anm.c b/ffmpeg/libavformat/anm.c deleted file mode 100644 index 1c58575..0000000 --- a/ffmpeg/libavformat/anm.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Deluxe Paint Animation demuxer - * Copyright (c) 2009 Peter Ross - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/** - * @file - * Deluxe Paint Animation demuxer - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" - -typedef struct { - int base_record; - unsigned int nb_records; - int size; -} Page; - -typedef struct { - unsigned int nb_pages; /**< total pages in file */ - unsigned int nb_records; /**< total records in file */ - int page_table_offset; -#define MAX_PAGES 256 /**< Deluxe Paint hardcoded value */ - Page pt[MAX_PAGES]; /**< page table */ - int page; /**< current page (or AVERROR_xxx code) */ - int record; /**< current record (with in page) */ -} AnmDemuxContext; - -#define LPF_TAG MKTAG('L','P','F',' ') -#define ANIM_TAG MKTAG('A','N','I','M') - -static int probe(AVProbeData *p) -{ - /* verify tags and video dimensions */ - if (AV_RL32(&p->buf[0]) == LPF_TAG && - AV_RL32(&p->buf[16]) == ANIM_TAG && - AV_RL16(&p->buf[20]) && AV_RL16(&p->buf[22])) - return AVPROBE_SCORE_MAX; - return 0; -} - -/** - * @return page containing the requested record or AVERROR_XXX - */ -static int find_record(const AnmDemuxContext *anm, int record) -{ - int i; - - if (record >= anm->nb_records) - return AVERROR_EOF; - - for (i = 0; i < MAX_PAGES; i++) { - const Page *p = &anm->pt[i]; - if (p->nb_records > 0 && record >= p->base_record && record < p->base_record + p->nb_records) - return i; - } - - return AVERROR_INVALIDDATA; -} - -static int read_header(AVFormatContext *s) -{ - AnmDemuxContext *anm = s->priv_data; - AVIOContext *pb = s->pb; - AVStream *st; - int i, ret; - - avio_skip(pb, 4); /* magic number */ - if (avio_rl16(pb) != MAX_PAGES) { - avpriv_request_sample(s, "max_pages != " AV_STRINGIFY(MAX_PAGES)); - return AVERROR_PATCHWELCOME; - } - - anm->nb_pages = avio_rl16(pb); - anm->nb_records = avio_rl32(pb); - avio_skip(pb, 2); /* max records per page */ - anm->page_table_offset = avio_rl16(pb); - if (avio_rl32(pb) != ANIM_TAG) - return AVERROR_INVALIDDATA; - - /* video stream */ - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_ANM; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->width = avio_rl16(pb); - st->codec->height = avio_rl16(pb); - if (avio_r8(pb) != 0) - goto invalid; - avio_skip(pb, 1); /* frame rate multiplier info */ - - /* ignore last delta record (used for looping) */ - if (avio_r8(pb)) /* has_last_delta */ - anm->nb_records = FFMAX(anm->nb_records - 1, 0); - - avio_skip(pb, 1); /* last_delta_valid */ - - if (avio_r8(pb) != 0) - goto invalid; - - if (avio_r8(pb) != 1) - goto invalid; - - avio_skip(pb, 1); /* other recs per frame */ - - if (avio_r8(pb) != 1) - goto invalid; - - avio_skip(pb, 32); /* record_types */ - st->nb_frames = avio_rl32(pb); - avpriv_set_pts_info(st, 64, 1, avio_rl16(pb)); - avio_skip(pb, 58); - - /* color cycling and palette data */ - st->codec->extradata_size = 16*8 + 4*256; - st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) { - return AVERROR(ENOMEM); - } - ret = avio_read(pb, st->codec->extradata, st->codec->extradata_size); - if (ret < 0) - return ret; - - /* read page table */ - ret = avio_seek(pb, anm->page_table_offset, SEEK_SET); - if (ret < 0) - return ret; - - for (i = 0; i < MAX_PAGES; i++) { - Page *p = &anm->pt[i]; - p->base_record = avio_rl16(pb); - p->nb_records = avio_rl16(pb); - p->size = avio_rl16(pb); - } - - /* find page of first frame */ - anm->page = find_record(anm, 0); - if (anm->page < 0) { - return anm->page; - } - - anm->record = -1; - return 0; - -invalid: - avpriv_request_sample(s, "Invalid header element"); - return AVERROR_PATCHWELCOME; -} - -static int read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - AnmDemuxContext *anm = s->priv_data; - AVIOContext *pb = s->pb; - Page *p; - int tmp, record_size; - - if (url_feof(s->pb)) - return AVERROR(EIO); - - if (anm->page < 0) - return anm->page; - -repeat: - p = &anm->pt[anm->page]; - - /* parse page header */ - if (anm->record < 0) { - avio_seek(pb, anm->page_table_offset + MAX_PAGES*6 + (anm->page<<16), SEEK_SET); - avio_skip(pb, 8 + 2*p->nb_records); - anm->record = 0; - } - - /* if we have fetched all records in this page, then find the - next page and repeat */ - if (anm->record >= p->nb_records) { - anm->page = find_record(anm, p->base_record + p->nb_records); - if (anm->page < 0) - return anm->page; - anm->record = -1; - goto repeat; - } - - /* fetch record size */ - tmp = avio_tell(pb); - avio_seek(pb, anm->page_table_offset + MAX_PAGES*6 + (anm->page<<16) + - 8 + anm->record * 2, SEEK_SET); - record_size = avio_rl16(pb); - avio_seek(pb, tmp, SEEK_SET); - - /* fetch record */ - pkt->size = av_get_packet(s->pb, pkt, record_size); - if (pkt->size < 0) - return pkt->size; - if (p->base_record + anm->record == 0) - pkt->flags |= AV_PKT_FLAG_KEY; - - anm->record++; - return 0; -} - -AVInputFormat ff_anm_demuxer = { - .name = "anm", - .long_name = NULL_IF_CONFIG_SMALL("Deluxe Paint Animation"), - .priv_data_size = sizeof(AnmDemuxContext), - .read_probe = probe, - .read_header = read_header, - .read_packet = read_packet, -}; |
