History

avcodec: add QOI decoder and demuxer and parser and encoder and muxer

Paul B Mahol committed 4 years ago

Commit 973fab51 parent c6364b716 files · +417 −3Browse files

Unified · Split

16 files
  1. Changelog +1 −0
  2. libavcodec/Makefile +3 −0
  3. libavcodec/allcodecs.c +2 −0
  4. libavcodec/codec_desc.c +7 −0
  5. libavcodec/codec_id.h +1 −0
  6. libavcodec/parsers.c +1 −0
  7. libavcodec/qoi.h +35 −0
  8. libavcodec/qoi_parser.c +77 −0
  9. libavcodec/qoidec.c +126 −0
  10. libavcodec/qoienc.c +140 −0
  11. libavcodec/version.h +2 −2
  12. libavformat/Makefile +1 −0
  13. libavformat/allformats.c +1 −0
  14. libavformat/img2.c +1 −0
  15. libavformat/img2dec.c +18 −0
  16. libavformat/img2enc.c +1 −1
Changelog+1−0
@@ -18,6 +18,7 @@ version 5.1: · 17 unmodified lines
1818 - PGS subtitle frame merge bitstream filter
1919 - blurdetect filter
2020 - tiltshelf audio filter
21+- QOI image format support
2122
2223
2324 version 5.0:
libavcodec/Makefile+3−0
@@ -593,6 +593,8 @@ OBJS-$(CONFIG_QCELP_DECODER) += qcelpdec.o \ · 592 unmodified lines
593593 OBJS-$(CONFIG_QDM2_DECODER) += qdm2.o
594594 OBJS-$(CONFIG_QDMC_DECODER) += qdmc.o
595595 OBJS-$(CONFIG_QDRAW_DECODER) += qdrw.o
596+OBJS-$(CONFIG_QOI_DECODER) += qoidec.o
597+OBJS-$(CONFIG_QOI_ENCODER) += qoienc.o
596598 OBJS-$(CONFIG_QPEG_DECODER) += qpeg.o
597599 OBJS-$(CONFIG_QTRLE_DECODER) += qtrle.o
598600 OBJS-$(CONFIG_QTRLE_ENCODER) += qtrleenc.o
@@ -1151,6 +1153,7 @@ OBJS-$(CONFIG_OPUS_PARSER) += opus_parser.o opus.o opustab.o \ · 552 unmodified lines
11511153 opus_rc.o vorbis_data.o
11521154 OBJS-$(CONFIG_PNG_PARSER) += png_parser.o
11531155 OBJS-$(CONFIG_PNM_PARSER) += pnm_parser.o pnm.o
1156+OBJS-$(CONFIG_QOI_PARSER) += qoi_parser.o
11541157 OBJS-$(CONFIG_RV30_PARSER) += rv34_parser.o
11551158 OBJS-$(CONFIG_RV40_PARSER) += rv34_parser.o
11561159 OBJS-$(CONFIG_SBC_PARSER) += sbc_parser.o
libavcodec/allcodecs.c+2−0
@@ -269,6 +269,8 @@ extern const FFCodec ff_prosumer_decoder; · 268 unmodified lines
269269 extern const FFCodec ff_psd_decoder;
270270 extern const FFCodec ff_ptx_decoder;
271271 extern const FFCodec ff_qdraw_decoder;
272+extern const FFCodec ff_qoi_encoder;
273+extern const FFCodec ff_qoi_decoder;
272274 extern const FFCodec ff_qpeg_decoder;
273275 extern const FFCodec ff_qtrle_encoder;
274276 extern const FFCodec ff_qtrle_decoder;
libavcodec/codec_desc.c+7−0
@@ -1879,6 +1879,13 @@ static const AVCodecDescriptor codec_descriptors[] = { · 1878 unmodified lines
18791879 AV_CODEC_PROP_LOSSLESS,
18801880 .mime_types= MT("image/jxl"),
18811881 },
1882+ {
1883+ .id = AV_CODEC_ID_QOI,
1884+ .type = AVMEDIA_TYPE_VIDEO,
1885+ .name = "qoi",
1886+ .long_name = NULL_IF_CONFIG_SMALL("QOI (Quite OK Image)"),
1887+ .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
1888+ },
18821889
18831890 /* various PCM "codecs" */
18841891 {
libavcodec/codec_id.h+1−0
@@ -310,6 +310,7 @@ enum AVCodecID { · 309 unmodified lines
310310 AV_CODEC_ID_GEM,
311311 AV_CODEC_ID_VBN,
312312 AV_CODEC_ID_JPEGXL,
313+ AV_CODEC_ID_QOI,
313314
314315 /* various PCM "codecs" */
315316 AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
libavcodec/parsers.c+1−0
@@ -60,6 +60,7 @@ extern const AVCodecParser ff_mpegvideo_parser; · 59 unmodified lines
6060 extern const AVCodecParser ff_opus_parser;
6161 extern const AVCodecParser ff_png_parser;
6262 extern const AVCodecParser ff_pnm_parser;
63+extern const AVCodecParser ff_qoi_parser;
6364 extern const AVCodecParser ff_rv30_parser;
6465 extern const AVCodecParser ff_rv40_parser;
6566 extern const AVCodecParser ff_sbc_parser;
libavcodec/qoi.h+35−0
@@ -0,0 +1,35 @@
1+/*
2+ * QOI image format
3+ *
4+ * This file is part of FFmpeg.
5+ *
6+ * FFmpeg is free software; you can redistribute it and/or
7+ * modify it under the terms of the GNU Lesser General Public
8+ * License as published by the Free Software Foundation; either
9+ * version 2.1 of the License, or (at your option) any later version.
10+ *
11+ * FFmpeg is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+ * Lesser General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU Lesser General Public
17+ * License along with FFmpeg; if not, write to the Free Software
18+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19+ */
20+
21+#ifndef AVCODEC_QOI_H
22+#define AVCODEC_QOI_H
23+
24+#define QOI_OP_INDEX 0x00 /* 00xxxxxx */
25+#define QOI_OP_DIFF 0x40 /* 01xxxxxx */
26+#define QOI_OP_LUMA 0x80 /* 10xxxxxx */
27+#define QOI_OP_RUN 0xc0 /* 11xxxxxx */
28+#define QOI_OP_RGB 0xfe /* 11111110 */
29+#define QOI_OP_RGBA 0xff /* 11111111 */
30+
31+#define QOI_MASK_2 0xc0 /* 11000000 */
32+
33+#define QOI_COLOR_HASH(px) (px[0]*3 + px[1]*5 + px[2]*7 + px[3]*11)
34+
35+#endif /* AVCODEC_QOI_H */
libavcodec/qoi_parser.c+77−0
@@ -0,0 +1,77 @@
1+/*
2+ * QOI parser
3+ * Copyright (c) 2022 Paul B Mahol
4+ *
5+ * This file is part of FFmpeg.
6+ *
7+ * FFmpeg is free software; you can redistribute it and/or
8+ * modify it under the terms of the GNU Lesser General Public
9+ * License as published by the Free Software Foundation; either
10+ * version 2.1 of the License, or (at your option) any later version.
11+ *
12+ * FFmpeg is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+ * Lesser General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU Lesser General Public
18+ * License along with FFmpeg; if not, write to the Free Software
19+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20+ */
21+
22+/**
23+ * @file
24+ * QOI parser
25+ */
26+
27+#include "parser.h"
28+
29+typedef struct QOIParseContext {
30+ ParseContext pc;
31+} QOIParseContext;
32+
33+static int qoi_parse(AVCodecParserContext *s, AVCodecContext *avctx,
34+ const uint8_t **poutbuf, int *poutbuf_size,
35+ const uint8_t *buf, int buf_size)
36+{
37+ QOIParseContext *ipc = s->priv_data;
38+ uint64_t state = ipc->pc.state64;
39+ int next = END_NOT_FOUND, i = 0;
40+
41+ s->pict_type = AV_PICTURE_TYPE_NONE;
42+ s->duration = 1;
43+
44+ *poutbuf_size = 0;
45+ *poutbuf = NULL;
46+
47+ if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
48+ next = buf_size;
49+ } else {
50+ for (; i < buf_size; i++) {
51+ state = (state << 8) | buf[i];
52+ if (state == 0x01LL) {
53+ next = i + 1;
54+ break;
55+ }
56+ }
57+
58+ ipc->pc.state64 = state;
59+ if (ff_combine_frame(&ipc->pc, next, &buf, &buf_size) < 0) {
60+ *poutbuf = NULL;
61+ *poutbuf_size = 0;
62+ return buf_size;
63+ }
64+ }
65+
66+ *poutbuf = buf;
67+ *poutbuf_size = buf_size;
68+
69+ return next;
70+}
71+
72+const AVCodecParser ff_qoi_parser = {
73+ .codec_ids = { AV_CODEC_ID_QOI },
74+ .priv_data_size = sizeof(QOIParseContext),
75+ .parser_parse = qoi_parse,
76+ .parser_close = ff_parse_close,
77+};
libavcodec/qoidec.c+126−0
@@ -0,0 +1,126 @@
1+/*
2+ * QOI image format
3+ *
4+ * This file is part of FFmpeg.
5+ *
6+ * FFmpeg is free software; you can redistribute it and/or
7+ * modify it under the terms of the GNU Lesser General Public
8+ * License as published by the Free Software Foundation; either
9+ * version 2.1 of the License, or (at your option) any later version.
10+ *
11+ * FFmpeg is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+ * Lesser General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU Lesser General Public
17+ * License along with FFmpeg; if not, write to the Free Software
18+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19+ */
20+
21+#include <stdlib.h>
22+
23+#include "libavutil/imgutils.h"
24+#include "avcodec.h"
25+#include "internal.h"
26+#include "bytestream.h"
27+#include "codec_internal.h"
28+#include "thread.h"
29+#include "qoi.h"
30+
31+static int qoi_decode_frame(AVCodecContext *avctx, AVFrame *p,
32+ int *got_frame, AVPacket *avpkt)
33+{
34+ const uint8_t *buf = avpkt->data;
35+ int ret, buf_size = avpkt->size;
36+ int width, height, channels, space, run = 0;
37+ uint8_t index[64][4] = { 0 };
38+ uint8_t px[4] = { 0, 0, 0, 255 };
39+ GetByteContext gb;
40+ uint8_t *dst;
41+ uint64_t len;
42+
43+ if (buf_size < 20)
44+ return AVERROR_INVALIDDATA;
45+
46+ bytestream2_init(&gb, buf, buf_size);
47+ bytestream2_skip(&gb, 4);
48+ width = bytestream2_get_be32(&gb);
49+ height = bytestream2_get_be32(&gb);
50+ channels = bytestream2_get_byte(&gb);
51+ space = bytestream2_get_byte(&gb);
52+ switch (space) {
53+ case 0: break;
54+ case 1: avctx->color_trc = AVCOL_TRC_LINEAR; break;
55+ default: return AVERROR_INVALIDDATA;
56+ }
57+
58+ if ((ret = ff_set_dimensions(avctx, width, height)) < 0)
59+ return ret;
60+
61+ switch (channels) {
62+ case 3: avctx->pix_fmt = AV_PIX_FMT_RGB24; break;
63+ case 4: avctx->pix_fmt = AV_PIX_FMT_RGBA; break;
64+ default: return AVERROR_INVALIDDATA;
65+ }
66+
67+ if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0)
68+ return ret;
69+
70+ dst = p->data[0];
71+ len = width * height * channels;
72+ for (int n = 0, off_x = 0, off_y = 0; n < len; n += channels, off_x++) {
73+ if (off_x >= width) {
74+ off_x = 0;
75+ off_y++;
76+ dst += p->linesize[0];
77+ }
78+ if (run > 0) {
79+ run--;
80+ } else if (bytestream2_get_bytes_left(&gb) > 4) {
81+ int chunk = bytestream2_get_byteu(&gb);
82+
83+ if (chunk == QOI_OP_RGB) {
84+ bytestream2_get_bufferu(&gb, px, 3);
85+ } else if (chunk == QOI_OP_RGBA) {
86+ bytestream2_get_bufferu(&gb, px, 4);
87+ } else if ((chunk & QOI_MASK_2) == QOI_OP_INDEX) {
88+ memcpy(px, index[chunk], 4);
89+ } else if ((chunk & QOI_MASK_2) == QOI_OP_DIFF) {
90+ px[0] += ((chunk >> 4) & 0x03) - 2;
91+ px[1] += ((chunk >> 2) & 0x03) - 2;
92+ px[2] += ( chunk & 0x03) - 2;
93+ } else if ((chunk & QOI_MASK_2) == QOI_OP_LUMA) {
94+ int b2 = bytestream2_get_byteu(&gb);
95+ int vg = (chunk & 0x3f) - 32;
96+ px[0] += vg - 8 + ((b2 >> 4) & 0x0f);
97+ px[1] += vg;
98+ px[2] += vg - 8 + (b2 & 0x0f);
99+ } else if ((chunk & QOI_MASK_2) == QOI_OP_RUN) {
100+ run = chunk & 0x3f;
101+ }
102+
103+ memcpy(index[QOI_COLOR_HASH(px) & 63], px, 4);
104+ } else {
105+ break;
106+ }
107+
108+ memcpy(&dst[off_x * channels], px, channels);
109+ }
110+
111+ p->key_frame = 1;
112+ p->pict_type = AV_PICTURE_TYPE_I;
113+
114+ *got_frame = 1;
115+
116+ return buf_size;
117+}
118+
119+const FFCodec ff_qoi_decoder = {
120+ .p.name = "qoi",
121+ .p.long_name = NULL_IF_CONFIG_SMALL("QOI (Quite OK Image format) image"),
122+ .p.type = AVMEDIA_TYPE_VIDEO,
123+ .p.id = AV_CODEC_ID_QOI,
124+ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
125+ FF_CODEC_DECODE_CB(qoi_decode_frame),
126+};
libavcodec/qoienc.c+140−0
@@ -0,0 +1,140 @@
1+/*
2+ * QOI image format encoder
3+ *
4+ * This file is part of FFmpeg.
5+ *
6+ * FFmpeg is free software; you can redistribute it and/or
7+ * modify it under the terms of the GNU Lesser General Public
8+ * License as published by the Free Software Foundation; either
9+ * version 2.1 of the License, or (at your option) any later version.
10+ *
11+ * FFmpeg is distributed in the hope that it will be useful,
12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+ * Lesser General Public License for more details.
15+ *
16+ * You should have received a copy of the GNU Lesser General Public
17+ * License along with FFmpeg; if not, write to the Free Software
18+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19+ */
20+
21+#include "libavutil/imgutils.h"
22+#include "avcodec.h"
23+#include "bytestream.h"
24+#include "codec_internal.h"
25+#include "encode.h"
26+#include "qoi.h"
27+
28+static int qoi_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
29+ const AVFrame *pict, int *got_packet)
30+{
31+ const int channels = 3 + (avctx->pix_fmt == AV_PIX_FMT_RGBA);
32+ uint8_t px_prev[4] = { 0, 0, 0, 255 };
33+ uint8_t px[4] = { 0, 0, 0, 255 };
34+ uint8_t index[64][4] = { 0 };
35+ int64_t packet_size;
36+ uint8_t *buf, *src;
37+ int ret, run = 0;
38+
39+ packet_size = avctx->width * avctx->height * (channels + 1LL) + 14LL + 8LL;
40+ if ((ret = ff_alloc_packet(avctx, pkt, packet_size)) < 0)
41+ return ret;
42+
43+ buf = pkt->data;
44+ src = pict->data[0];
45+
46+ bytestream_put_buffer(&buf, "qoif", 4);
47+ bytestream_put_be32(&buf, avctx->width);
48+ bytestream_put_be32(&buf, avctx->height);
49+ bytestream_put_byte(&buf, channels);
50+ bytestream_put_byte(&buf, avctx->color_trc == AVCOL_TRC_LINEAR);
51+
52+ for (int y = 0; y < avctx->height; y++) {
53+ for (int x = 0; x < avctx->width; x++) {
54+ memcpy(px, src + x * channels, channels);
55+
56+ if (!memcmp(px, px_prev, 4)) {
57+ run++;
58+ if (run == 62) {
59+ bytestream_put_byte(&buf, QOI_OP_RUN | (run - 1));
60+ run = 0;
61+ }
62+ } else {
63+ int index_pos;
64+
65+ if (run > 0) {
66+ bytestream_put_byte(&buf, QOI_OP_RUN | (run - 1));
67+ run = 0;
68+ }
69+
70+ index_pos = QOI_COLOR_HASH(px) & 63;
71+
72+ if (!memcmp(index[index_pos], px, 4)) {
73+ bytestream_put_byte(&buf, QOI_OP_INDEX | index_pos);
74+ } else {
75+ memcpy(index[index_pos], px, 4);
76+
77+ if (px[3] == px_prev[3]) {
78+ int8_t vr = px[0] - px_prev[0];
79+ int8_t vg = px[1] - px_prev[1];
80+ int8_t vb = px[2] - px_prev[2];
81+
82+ int8_t vg_r = vr - vg;
83+ int8_t vg_b = vb - vg;
84+
85+ if (vr > -3 && vr < 2 &&
86+ vg > -3 && vg < 2 &&
87+ vb > -3 && vb < 2) {
88+ bytestream_put_byte(&buf, QOI_OP_DIFF | (vr + 2) << 4 | (vg + 2) << 2 | (vb + 2));
89+ } else if (vg_r > -9 && vg_r < 8 &&
90+ vg > -33 && vg < 32 &&
91+ vg_b > -9 && vg_b < 8) {
92+ bytestream_put_byte(&buf, QOI_OP_LUMA | (vg + 32));
93+ bytestream_put_byte(&buf, (vg_r + 8) << 4 | (vg_b + 8));
94+ } else {
95+ bytestream_put_byte(&buf, QOI_OP_RGB);
96+ bytestream_put_byte(&buf, px[0]);
97+ bytestream_put_byte(&buf, px[1]);
98+ bytestream_put_byte(&buf, px[2]);
99+ }
100+ } else {
101+ bytestream_put_byte(&buf, QOI_OP_RGBA);
102+ bytestream_put_byte(&buf, px[0]);
103+ bytestream_put_byte(&buf, px[1]);
104+ bytestream_put_byte(&buf, px[2]);
105+ bytestream_put_byte(&buf, px[3]);
106+ }
107+ }
108+ }
109+
110+ memcpy(px_prev, px, 4);
111+ }
112+
113+ src += pict->linesize[0];
114+ }
115+
116+ if (run)
117+ bytestream_put_byte(&buf, QOI_OP_RUN | (run - 1));
118+
119+ bytestream_put_be64(&buf, 0x01);
120+
121+ pkt->size = buf - pkt->data;
122+
123+ *got_packet = 1;
124+
125+ return 0;
126+}
127+
128+const FFCodec ff_qoi_encoder = {
129+ .p.name = "qoi",
130+ .p.long_name = NULL_IF_CONFIG_SMALL("QOI (Quite OK Image format) image"),
131+ .p.type = AVMEDIA_TYPE_VIDEO,
132+ .p.id = AV_CODEC_ID_QOI,
133+ .p.capabilities = AV_CODEC_CAP_FRAME_THREADS,
134+ FF_CODEC_ENCODE_CB(qoi_encode_frame),
135+ .p.pix_fmts = (const enum AVPixelFormat[]){
136+ AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB24,
137+ AV_PIX_FMT_NONE
138+ },
139+ .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
140+};
libavcodec/version.h+2−2
@@ -29,8 +29,8 @@ · 28 unmodified lines
2929
3030 #include "version_major.h"
3131
32−#define LIBAVCODEC_VERSION_MINOR 32
33−#define LIBAVCODEC_VERSION_MICRO 102
32+#define LIBAVCODEC_VERSION_MINOR 33
33+#define LIBAVCODEC_VERSION_MICRO 100
3434
3535 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
3636 LIBAVCODEC_VERSION_MINOR, \
libavformat/Makefile+1−0
@@ -289,6 +289,7 @@ OBJS-$(CONFIG_IMAGE_PNG_PIPE_DEMUXER) += img2dec.o img2.o · 288 unmodified lines
289289 OBJS-$(CONFIG_IMAGE_PPM_PIPE_DEMUXER) += img2dec.o img2.o
290290 OBJS-$(CONFIG_IMAGE_PSD_PIPE_DEMUXER) += img2dec.o img2.o
291291 OBJS-$(CONFIG_IMAGE_QDRAW_PIPE_DEMUXER) += img2dec.o img2.o
292+OBJS-$(CONFIG_IMAGE_QOI_PIPE_DEMUXER) += img2dec.o img2.o
292293 OBJS-$(CONFIG_IMAGE_SGI_PIPE_DEMUXER) += img2dec.o img2.o
293294 OBJS-$(CONFIG_IMAGE_SVG_PIPE_DEMUXER) += img2dec.o img2.o
294295 OBJS-$(CONFIG_IMAGE_SUNRAST_PIPE_DEMUXER) += img2dec.o img2.o
libavformat/allformats.c+1−0
@@ -524,6 +524,7 @@ extern const AVInputFormat ff_image_png_pipe_demuxer; · 523 unmodified lines
524524 extern const AVInputFormat ff_image_ppm_pipe_demuxer;
525525 extern const AVInputFormat ff_image_psd_pipe_demuxer;
526526 extern const AVInputFormat ff_image_qdraw_pipe_demuxer;
527+extern const AVInputFormat ff_image_qoi_pipe_demuxer;
527528 extern const AVInputFormat ff_image_sgi_pipe_demuxer;
528529 extern const AVInputFormat ff_image_svg_pipe_demuxer;
529530 extern const AVInputFormat ff_image_sunrast_pipe_demuxer;
libavformat/img2.c+1−0
@@ -89,6 +89,7 @@ const IdStrMap ff_img_tags[] = { · 88 unmodified lines
8989 { AV_CODEC_ID_GEM, "timg" },
9090 { AV_CODEC_ID_VBN, "vbn" },
9191 { AV_CODEC_ID_JPEGXL, "jxl" },
92+ { AV_CODEC_ID_QOI, "qoi" },
9293 { AV_CODEC_ID_NONE, NULL }
9394 };
9495
libavformat/img2dec.c+18−0
@@ -1131,6 +1131,23 @@ static int photocd_probe(const AVProbeData *p) · 1130 unmodified lines
11311131 return AVPROBE_SCORE_MAX - 1;
11321132 }
11331133
1134+static int qoi_probe(const AVProbeData *p)
1135+{
1136+ if (memcmp(p->buf, "qoif", 4))
1137+ return 0;
1138+
1139+ if (AV_RB32(p->buf + 4) == 0 || AV_RB32(p->buf + 8) == 0)
1140+ return 0;
1141+
1142+ if (p->buf[12] != 3 && p->buf[12] != 4)
1143+ return 0;
1144+
1145+ if (p->buf[13] > 1)
1146+ return 0;
1147+
1148+ return AVPROBE_SCORE_MAX - 1;
1149+}
1150+
11341151 static int gem_probe(const AVProbeData *p)
11351152 {
11361153 const uint8_t *b = p->buf;
@@ -1208,6 +1225,7 @@ IMAGEAUTO_DEMUXER(png, PNG) · 71 unmodified lines
12081225 IMAGEAUTO_DEMUXER(ppm, PPM)
12091226 IMAGEAUTO_DEMUXER(psd, PSD)
12101227 IMAGEAUTO_DEMUXER(qdraw, QDRAW)
1228+IMAGEAUTO_DEMUXER(qoi, QOI)
12111229 IMAGEAUTO_DEMUXER(sgi, SGI)
12121230 IMAGEAUTO_DEMUXER(sunrast, SUNRAST)
12131231 IMAGEAUTO_DEMUXER(svg, SVG)
libavformat/img2enc.c+1−1
@@ -267,7 +267,7 @@ const AVOutputFormat ff_image2_muxer = { · 266 unmodified lines
267267 .long_name = NULL_IF_CONFIG_SMALL("image2 sequence"),
268268 .extensions = "bmp,dpx,exr,jls,jpeg,jpg,jxl,ljpg,pam,pbm,pcx,pfm,pgm,pgmyuv,"
269269 "png,ppm,sgi,tga,tif,tiff,jp2,j2c,j2k,xwd,sun,ras,rs,im1,im8,"
270− "im24,sunras,vbn,xbm,xface,pix,y,avif",
270+ "im24,sunras,vbn,xbm,xface,pix,y,avif,qoi",
271271 .priv_data_size = sizeof(VideoMuxData),
272272 .video_codec = AV_CODEC_ID_MJPEG,
273273 .write_header = write_header,

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t