diff options
author | Paul B Mahol <onemda@gmail.com> | 2022-09-16 12:05:44 +0200 |
---|---|---|
committer | Paul B Mahol <onemda@gmail.com> | 2022-09-17 10:15:01 +0200 |
commit | 79dcee34dddf7c82d2e865f07b7b9887d3fb16a3 (patch) | |
tree | 9a9817dcb06ab193d42de8da5c8bcddf5ce61720 /libavcodec | |
parent | 695bf82bfb233fa0e77af4029c88620d943c3cba (diff) | |
download | ffmpeg-79dcee34dddf7c82d2e865f07b7b9887d3fb16a3.tar.gz |
avcodec: add XWD parser
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/Makefile | 1 | ||||
-rw-r--r-- | libavcodec/parsers.c | 1 | ||||
-rw-r--r-- | libavcodec/xwd_parser.c | 103 |
3 files changed, 105 insertions, 0 deletions
diff --git a/libavcodec/Makefile b/libavcodec/Makefile index e23b03e5dd..c836252664 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -1170,6 +1170,7 @@ OBJS-$(CONFIG_VP9_PARSER) += vp9_parser.o OBJS-$(CONFIG_WEBP_PARSER) += webp_parser.o OBJS-$(CONFIG_XBM_PARSER) += xbm_parser.o OBJS-$(CONFIG_XMA_PARSER) += xma_parser.o +OBJS-$(CONFIG_XWD_PARSER) += xwd_parser.o # bitstream filters OBJS-$(CONFIG_AAC_ADTSTOASC_BSF) += aac_adtstoasc_bsf.o diff --git a/libavcodec/parsers.c b/libavcodec/parsers.c index 362f6f8bc6..bcba94ca69 100644 --- a/libavcodec/parsers.c +++ b/libavcodec/parsers.c @@ -76,6 +76,7 @@ extern const AVCodecParser ff_vp9_parser; extern const AVCodecParser ff_webp_parser; extern const AVCodecParser ff_xbm_parser; extern const AVCodecParser ff_xma_parser; +extern const AVCodecParser ff_xwd_parser; #include "libavcodec/parser_list.c" diff --git a/libavcodec/xwd_parser.c b/libavcodec/xwd_parser.c new file mode 100644 index 0000000000..ab5fe86070 --- /dev/null +++ b/libavcodec/xwd_parser.c @@ -0,0 +1,103 @@ +/* + * XWD parser + * Copyright (c) 2022 Paul B Mahol + * + * 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 + * XWD parser + **/ + +#include "libavutil/intreadwrite.h" +#include "parser.h" +#include "xwd.h" + +typedef struct XWDParseContext { + ParseContext pc; + int left; + int idx; + uint8_t hdr[XWD_HEADER_SIZE]; +} XWDParseContext; + +static int xwd_parse(AVCodecParserContext *s, AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + XWDParseContext *t = s->priv_data; + ParseContext *pc = &t->pc; + int next = END_NOT_FOUND; + + s->pict_type = AV_PICTURE_TYPE_NONE; + + *poutbuf = NULL; + *poutbuf_size = 0; + + if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { + next = buf_size; + } else { + for (int i = 0; i < buf_size; i++) { + if (t->left > 0) { + t->left--; + if (t->left == 0) { + next = i; + break; + } + continue; + } + + if (t->idx >= 100) { + t->idx = 99; + memmove(&t->hdr[0], &t->hdr[1], XWD_HEADER_SIZE-1); + } + + t->hdr[t->idx++] = buf[i]; + + if (t->idx >= 100 && AV_RB32(t->hdr + 4) == XWD_VERSION) { + uint32_t header_size = AV_RB32(t->hdr + 0); + uint32_t height = AV_RB32(t->hdr + 20); + uint32_t lsize = AV_RB32(t->hdr + 48); + uint32_t ncolors = AV_RB32(t->hdr + 76); + uint32_t size = header_size + ncolors * XWD_CMAP_SIZE + height * lsize; + pc->frame_start_found = 1; + t->left = size - XWD_HEADER_SIZE + 1; + t->idx = 0; + memset(t->hdr, 0, sizeof(t->hdr)); + } + } + + if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) + return buf_size; + } + + *poutbuf = buf; + *poutbuf_size = buf_size; + + s->pict_type = AV_PICTURE_TYPE_I; + s->key_frame = 1; + s->duration = 1; + + return next; +} + +const AVCodecParser ff_xwd_parser = { + .codec_ids = { AV_CODEC_ID_XWD }, + .priv_data_size = sizeof(XWDParseContext), + .parser_parse = xwd_parse, + .parser_close = ff_parse_close, +}; |