mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-08 13:22:53 +02:00
avformat/image2: add Jpeg XL as image2 format
This commit adds support to libavformat for muxing and demuxing Jpeg XL images as image2 streams.
This commit is contained in:
parent
5f0b4e9c70
commit
3ac23440ef
@ -439,6 +439,7 @@ Muxers/Demuxers:
|
||||
ipmovie.c Mike Melanson
|
||||
ircam* Paul B Mahol
|
||||
iss.c Stefan Gehrer
|
||||
jpegxl_probe.* Leo Izen
|
||||
jvdec.c Peter Ross
|
||||
kvag.c Zane van Iperen
|
||||
libmodplug.c Clément Bœsch
|
||||
|
@ -272,6 +272,7 @@ OBJS-$(CONFIG_IMAGE_GIF_PIPE_DEMUXER) += img2dec.o img2.o
|
||||
OBJS-$(CONFIG_IMAGE_J2K_PIPE_DEMUXER) += img2dec.o img2.o
|
||||
OBJS-$(CONFIG_IMAGE_JPEG_PIPE_DEMUXER) += img2dec.o img2.o
|
||||
OBJS-$(CONFIG_IMAGE_JPEGLS_PIPE_DEMUXER) += img2dec.o img2.o
|
||||
OBJS-$(CONFIG_IMAGE_JPEGXL_PIPE_DEMUXER) += img2dec.o img2.o jpegxl_probe.o
|
||||
OBJS-$(CONFIG_IMAGE_PAM_PIPE_DEMUXER) += img2dec.o img2.o
|
||||
OBJS-$(CONFIG_IMAGE_PBM_PIPE_DEMUXER) += img2dec.o img2.o
|
||||
OBJS-$(CONFIG_IMAGE_PCX_PIPE_DEMUXER) += img2dec.o img2.o
|
||||
|
@ -510,6 +510,7 @@ extern const AVInputFormat ff_image_gif_pipe_demuxer;
|
||||
extern const AVInputFormat ff_image_j2k_pipe_demuxer;
|
||||
extern const AVInputFormat ff_image_jpeg_pipe_demuxer;
|
||||
extern const AVInputFormat ff_image_jpegls_pipe_demuxer;
|
||||
extern const AVInputFormat ff_image_jpegxl_pipe_demuxer;
|
||||
extern const AVInputFormat ff_image_pam_pipe_demuxer;
|
||||
extern const AVInputFormat ff_image_pbm_pipe_demuxer;
|
||||
extern const AVInputFormat ff_image_pcx_pipe_demuxer;
|
||||
|
@ -88,6 +88,7 @@ const IdStrMap ff_img_tags[] = {
|
||||
{ AV_CODEC_ID_GEM, "ximg" },
|
||||
{ AV_CODEC_ID_GEM, "timg" },
|
||||
{ AV_CODEC_ID_VBN, "vbn" },
|
||||
{ AV_CODEC_ID_JPEGXL, "jxl" },
|
||||
{ AV_CODEC_ID_NONE, NULL }
|
||||
};
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "avio_internal.h"
|
||||
#include "internal.h"
|
||||
#include "img2.h"
|
||||
#include "jpegxl_probe.h"
|
||||
#include "libavcodec/mjpeg.h"
|
||||
#include "libavcodec/vbn.h"
|
||||
#include "libavcodec/xwd.h"
|
||||
@ -837,6 +838,24 @@ static int jpegls_probe(const AVProbeData *p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int jpegxl_probe(const AVProbeData *p)
|
||||
{
|
||||
const uint8_t *b = p->buf;
|
||||
|
||||
/* ISOBMFF-based container */
|
||||
/* 0x4a584c20 == "JXL " */
|
||||
if (AV_RL64(b) == FF_JPEGXL_CONTAINER_SIGNATURE_LE)
|
||||
return AVPROBE_SCORE_EXTENSION + 1;
|
||||
/* Raw codestreams all start with 0xff0a */
|
||||
if (AV_RL16(b) != FF_JPEGXL_CODESTREAM_SIGNATURE_LE)
|
||||
return 0;
|
||||
#if CONFIG_IMAGE_JPEGXL_PIPE_DEMUXER
|
||||
if (ff_jpegxl_verify_codestream_header(p->buf, p->buf_size) >= 0)
|
||||
return AVPROBE_SCORE_MAX - 2;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pcx_probe(const AVProbeData *p)
|
||||
{
|
||||
const uint8_t *b = p->buf;
|
||||
@ -1176,6 +1195,7 @@ IMAGEAUTO_DEMUXER(gif, GIF)
|
||||
IMAGEAUTO_DEMUXER_EXT(j2k, JPEG2000, J2K)
|
||||
IMAGEAUTO_DEMUXER_EXT(jpeg, MJPEG, JPEG)
|
||||
IMAGEAUTO_DEMUXER(jpegls, JPEGLS)
|
||||
IMAGEAUTO_DEMUXER(jpegxl, JPEGXL)
|
||||
IMAGEAUTO_DEMUXER(pam, PAM)
|
||||
IMAGEAUTO_DEMUXER(pbm, PBM)
|
||||
IMAGEAUTO_DEMUXER(pcx, PCX)
|
||||
|
@ -263,9 +263,9 @@ static const AVClass img2mux_class = {
|
||||
const AVOutputFormat ff_image2_muxer = {
|
||||
.name = "image2",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("image2 sequence"),
|
||||
.extensions = "bmp,dpx,exr,jls,jpeg,jpg,ljpg,pam,pbm,pcx,pfm,pgm,pgmyuv,png,"
|
||||
"ppm,sgi,tga,tif,tiff,jp2,j2c,j2k,xwd,sun,ras,rs,im1,im8,im24,"
|
||||
"sunras,vbn,xbm,xface,pix,y",
|
||||
.extensions = "bmp,dpx,exr,jls,jpeg,jpg,jxl,ljpg,pam,pbm,pcx,pfm,pgm,pgmyuv,"
|
||||
"png,ppm,sgi,tga,tif,tiff,jp2,j2c,j2k,xwd,sun,ras,rs,im1,im8,"
|
||||
"im24,sunras,vbn,xbm,xface,pix,y",
|
||||
.priv_data_size = sizeof(VideoMuxData),
|
||||
.video_codec = AV_CODEC_ID_MJPEG,
|
||||
.write_header = write_header,
|
||||
|
393
libavformat/jpegxl_probe.c
Normal file
393
libavformat/jpegxl_probe.c
Normal file
@ -0,0 +1,393 @@
|
||||
/*
|
||||
* Jpeg XL header verification
|
||||
* Copyright (c) 2022 Leo Izen <leo.izen@gmail.com>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "jpegxl_probe.h"
|
||||
|
||||
#define BITSTREAM_READER_LE
|
||||
#include "libavcodec/get_bits.h"
|
||||
|
||||
enum JpegXLExtraChannelType {
|
||||
FF_JPEGXL_CT_ALPHA = 0,
|
||||
FF_JPEGXL_CT_DEPTH,
|
||||
FF_JPEGXL_CT_SPOT_COLOR,
|
||||
FF_JPEGXL_CT_SELECTION_MASK,
|
||||
FF_JPEGXL_CT_BLACK,
|
||||
FF_JPEGXL_CT_CFA,
|
||||
FF_JPEGXL_CT_THERMAL,
|
||||
FF_JPEGXL_CT_NON_OPTIONAL = 15,
|
||||
FF_JPEGXL_CT_OPTIONAL
|
||||
};
|
||||
|
||||
enum JpegXLColorSpace {
|
||||
FF_JPEGXL_CS_RGB = 0,
|
||||
FF_JPEGXL_CS_GRAY,
|
||||
FF_JPEGXL_CS_XYB,
|
||||
FF_JPEGXL_CS_UNKNOWN
|
||||
};
|
||||
|
||||
enum JpegXLWhitePoint {
|
||||
FF_JPEGXL_WP_D65 = 1,
|
||||
FF_JPEGXL_WP_CUSTOM,
|
||||
FF_JPEGXL_WP_E = 10,
|
||||
FF_JPEGXL_WP_DCI = 11
|
||||
};
|
||||
|
||||
enum JpegXLPrimaries {
|
||||
FF_JPEGXL_PR_SRGB = 1,
|
||||
FF_JPEGXL_PR_CUSTOM,
|
||||
FF_JPEGXL_PR_2100 = 9,
|
||||
FF_JPEGXL_PR_P3 = 11,
|
||||
};
|
||||
|
||||
#define jxl_bits(n) get_bits_long(gb, (n))
|
||||
#define jxl_bits_skip(n) skip_bits_long(gb, (n))
|
||||
#define jxl_u32(c0, c1, c2, c3, u0, u1, u2, u3) jpegxl_u32(gb, \
|
||||
(const uint32_t[]){c0, c1, c2, c3}, (const uint32_t[]){u0, u1, u2, u3})
|
||||
#define jxl_u64() jpegxl_u64(gb)
|
||||
#define jxl_enum() jxl_u32(0, 1, 2, 18, 0, 0, 4, 6)
|
||||
|
||||
/* read a U32(c_i + u(u_i)) */
|
||||
static uint32_t jpegxl_u32(GetBitContext *gb,
|
||||
const uint32_t constants[4], const uint32_t ubits[4])
|
||||
{
|
||||
uint32_t ret, choice = jxl_bits(2);
|
||||
|
||||
ret = constants[choice];
|
||||
if (ubits[choice])
|
||||
ret += jxl_bits(ubits[choice]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* read a U64() */
|
||||
static uint64_t jpegxl_u64(GetBitContext *gb)
|
||||
{
|
||||
uint64_t shift = 12, ret;
|
||||
|
||||
switch (jxl_bits(2)) {
|
||||
case 0:
|
||||
ret = 0;
|
||||
break;
|
||||
case 1:
|
||||
ret = 1 + jxl_bits(4);
|
||||
break;
|
||||
case 2:
|
||||
ret = 17 + jxl_bits(8);
|
||||
break;
|
||||
case 3:
|
||||
ret = jxl_bits(12);
|
||||
while (jxl_bits(1)) {
|
||||
if (shift < 60) {
|
||||
ret |= jxl_bits(8) << shift;
|
||||
shift += 8;
|
||||
} else {
|
||||
ret |= jxl_bits(4) << shift;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint32_t jpegxl_width_from_ratio(uint32_t height, int ratio)
|
||||
{
|
||||
uint64_t height64 = height; /* avoid integer overflow */
|
||||
switch (ratio) {
|
||||
case 1:
|
||||
return height;
|
||||
case 2:
|
||||
return (uint32_t)((height64 * 12) / 10);
|
||||
case 3:
|
||||
return (uint32_t)((height64 * 4) / 3);
|
||||
case 4:
|
||||
return (uint32_t)((height64 * 3) / 2);
|
||||
case 5:
|
||||
return (uint32_t)((height64 * 16) / 9);
|
||||
case 6:
|
||||
return (uint32_t)((height64 * 5) / 4);
|
||||
case 7:
|
||||
return (uint32_t)(height64 * 2);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0; /* manual width */
|
||||
}
|
||||
|
||||
/**
|
||||
* validate a Jpeg XL Size Header
|
||||
* @return >= 0 upon valid size, < 0 upon invalid size found
|
||||
*/
|
||||
static int jpegxl_read_size_header(GetBitContext *gb)
|
||||
{
|
||||
uint32_t width, height;
|
||||
|
||||
if (jxl_bits(1)) {
|
||||
/* small size header */
|
||||
height = (jxl_bits(5) + 1) << 3;
|
||||
width = jpegxl_width_from_ratio(height, jxl_bits(3));
|
||||
if (!width)
|
||||
width = (jxl_bits(5) + 1) << 3;
|
||||
} else {
|
||||
/* large size header */
|
||||
height = 1 + jxl_u32(0, 0, 0, 0, 9, 13, 18, 30);
|
||||
width = jpegxl_width_from_ratio(height, jxl_bits(3));
|
||||
if (!width)
|
||||
width = 1 + jxl_u32(0, 0, 0, 0, 9, 13, 18, 30);
|
||||
}
|
||||
if (width > (1 << 18) || height > (1 << 18)
|
||||
|| (width >> 4) * (height >> 4) > (1 << 20))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* validate a Jpeg XL Preview Header
|
||||
* @return >= 0 upon valid size, < 0 upon invalid size found
|
||||
*/
|
||||
static int jpegxl_read_preview_header(GetBitContext *gb)
|
||||
{
|
||||
uint32_t width, height;
|
||||
|
||||
if (jxl_bits(1)) {
|
||||
/* coded height and width divided by eight */
|
||||
height = jxl_u32(16, 32, 1, 33, 0, 0, 5, 9) << 3;
|
||||
width = jpegxl_width_from_ratio(height, jxl_bits(3));
|
||||
if (!width)
|
||||
width = jxl_u32(16, 32, 1, 33, 0, 0, 5, 9) << 3;
|
||||
} else {
|
||||
/* full height and width coded */
|
||||
height = jxl_u32(1, 65, 321, 1345, 6, 8, 10, 12);
|
||||
width = jpegxl_width_from_ratio(height, jxl_bits(3));
|
||||
if (!width)
|
||||
width = jxl_u32(1, 65, 321, 1345, 6, 8, 10, 12);
|
||||
}
|
||||
if (width > 4096 || height > 4096)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* skip a Jpeg XL BitDepth Header. These cannot be invalid.
|
||||
*/
|
||||
static void jpegxl_skip_bit_depth(GetBitContext *gb)
|
||||
{
|
||||
if (jxl_bits(1)) {
|
||||
/* float samples */
|
||||
jxl_u32(32, 16, 24, 1, 0, 0, 0, 6); /* mantissa */
|
||||
jxl_bits_skip(4); /* exponent */
|
||||
} else {
|
||||
/* integer samples */
|
||||
jxl_u32(8, 10, 12, 1, 0, 0, 0, 6);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* validate a Jpeg XL Extra Channel Info bundle
|
||||
* @return >= 0 upon valid, < 0 upon invalid
|
||||
*/
|
||||
static int jpegxl_read_extra_channel_info(GetBitContext *gb)
|
||||
{
|
||||
int all_default = jxl_bits(1);
|
||||
uint32_t type, name_len = 0;
|
||||
|
||||
if (!all_default) {
|
||||
type = jxl_enum();
|
||||
if (type > 63)
|
||||
return -1; /* enum types cannot be 64+ */
|
||||
if (type == FF_JPEGXL_CT_BLACK)
|
||||
return -1;
|
||||
jpegxl_skip_bit_depth(gb);
|
||||
jxl_u32(0, 3, 4, 1, 0, 0, 0, 3); /* dim-shift */
|
||||
/* max of name_len is 1071 = 48 + 2^10 - 1 */
|
||||
name_len = jxl_u32(0, 0, 16, 48, 0, 4, 5, 10);
|
||||
} else {
|
||||
type = FF_JPEGXL_CT_ALPHA;
|
||||
}
|
||||
|
||||
/* skip over the name */
|
||||
jxl_bits_skip(8 * name_len);
|
||||
|
||||
if (!all_default && type == FF_JPEGXL_CT_ALPHA)
|
||||
jxl_bits_skip(1);
|
||||
|
||||
if (type == FF_JPEGXL_CT_SPOT_COLOR)
|
||||
jxl_bits_skip(16 * 4);
|
||||
|
||||
if (type == FF_JPEGXL_CT_CFA)
|
||||
jxl_u32(1, 0, 3, 19, 0, 2, 4, 8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* verify that a codestream header is valid */
|
||||
int ff_jpegxl_verify_codestream_header(const uint8_t *buf, int buflen)
|
||||
{
|
||||
GetBitContext gbi, *gb = &gbi;
|
||||
int all_default, extra_fields = 0;
|
||||
int xyb_encoded = 1, have_icc_profile = 0;
|
||||
uint32_t num_extra_channels;
|
||||
uint64_t extensions;
|
||||
|
||||
init_get_bits8(gb, buf, buflen);
|
||||
|
||||
if (jxl_bits(16) != FF_JPEGXL_CODESTREAM_SIGNATURE_LE)
|
||||
return -1;
|
||||
|
||||
if (jpegxl_read_size_header(gb) < 0)
|
||||
return -1;
|
||||
|
||||
all_default = jxl_bits(1);
|
||||
if (!all_default)
|
||||
extra_fields = jxl_bits(1);
|
||||
|
||||
if (extra_fields) {
|
||||
jxl_bits_skip(3); /* orientation */
|
||||
|
||||
/*
|
||||
* intrinstic size
|
||||
* any size header here is valid, but as it
|
||||
* is variable length we have to read it
|
||||
*/
|
||||
if (jxl_bits(1))
|
||||
jpegxl_read_size_header(gb);
|
||||
|
||||
/* preview header */
|
||||
if (jxl_bits(1)) {
|
||||
if (jpegxl_read_preview_header(gb) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* animation header */
|
||||
if (jxl_bits(1)) {
|
||||
jxl_u32(100, 1000, 1, 1, 0, 0, 10, 30);
|
||||
jxl_u32(1, 1001, 1, 1, 0, 0, 8, 10);
|
||||
jxl_u32(0, 0, 0, 0, 0, 3, 16, 32);
|
||||
jxl_bits_skip(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!all_default) {
|
||||
jpegxl_skip_bit_depth(gb);
|
||||
|
||||
/* modular_16bit_buffers must equal 1 */
|
||||
if (!jxl_bits(1))
|
||||
return -1;
|
||||
|
||||
num_extra_channels = jxl_u32(0, 1, 2, 1, 0, 0, 4, 12);
|
||||
if (num_extra_channels > 4)
|
||||
return -1;
|
||||
for (uint32_t i = 0; i < num_extra_channels; i++) {
|
||||
if (jpegxl_read_extra_channel_info(gb) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
xyb_encoded = jxl_bits(1);
|
||||
|
||||
/* color encoding bundle */
|
||||
if (!jxl_bits(1)) {
|
||||
uint32_t color_space;
|
||||
have_icc_profile = jxl_bits(1);
|
||||
color_space = jxl_enum();
|
||||
if (color_space > 63)
|
||||
return -1;
|
||||
|
||||
if (!have_icc_profile) {
|
||||
if (color_space != FF_JPEGXL_CS_XYB) {
|
||||
uint32_t white_point = jxl_enum();
|
||||
if (white_point > 63)
|
||||
return -1;
|
||||
if (white_point == FF_JPEGXL_WP_CUSTOM) {
|
||||
/* ux and uy values */
|
||||
jxl_u32(0, 524288, 1048576, 2097152, 19, 19, 20, 21);
|
||||
jxl_u32(0, 524288, 1048576, 2097152, 19, 19, 20, 21);
|
||||
}
|
||||
if (color_space != FF_JPEGXL_CS_GRAY) {
|
||||
/* primaries */
|
||||
uint32_t primaries = jxl_enum();
|
||||
if (primaries > 63)
|
||||
return -1;
|
||||
if (primaries == FF_JPEGXL_PR_CUSTOM) {
|
||||
/* ux/uy values for r,g,b */
|
||||
for (int i = 0; i < 6; i++)
|
||||
jxl_u32(0, 524288, 1048576, 2097152, 19, 19, 20, 21);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* transfer characteristics */
|
||||
if (jxl_bits(1)) {
|
||||
/* gamma */
|
||||
jxl_bits_skip(24);
|
||||
} else {
|
||||
/* transfer function */
|
||||
if (jxl_enum() > 63)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* rendering intent */
|
||||
if (jxl_enum() > 63)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* tone mapping bundle */
|
||||
if (extra_fields && !jxl_bits(1))
|
||||
jxl_bits_skip(16 + 16 + 1 + 16);
|
||||
|
||||
extensions = jxl_u64();
|
||||
if (extensions) {
|
||||
for (int i = 0; i < 64; i++) {
|
||||
if (extensions & (UINT64_C(1) << i))
|
||||
jxl_u64();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* default transform */
|
||||
if (!jxl_bits(1)) {
|
||||
/* opsin inverse matrix */
|
||||
if (xyb_encoded && !jxl_bits(1))
|
||||
jxl_bits_skip(16 * 16);
|
||||
/* cw_mask and default weights */
|
||||
if (jxl_bits(1))
|
||||
jxl_bits_skip(16 * 15);
|
||||
if (jxl_bits(1))
|
||||
jxl_bits_skip(16 * 55);
|
||||
if (jxl_bits(1))
|
||||
jxl_bits_skip(16 * 210);
|
||||
}
|
||||
|
||||
if (!have_icc_profile) {
|
||||
int bits_remaining = 7 - (get_bits_count(gb) - 1) % 8;
|
||||
if (bits_remaining && jxl_bits(bits_remaining))
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (get_bits_left(gb) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
32
libavformat/jpegxl_probe.h
Normal file
32
libavformat/jpegxl_probe.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Jpeg XL header verification
|
||||
* Copyright (c) 2022 Leo Izen <leo.izen@gmail.com>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef AVFORMAT_JPEGXL_PROBE_H
|
||||
#define AVFORMAT_JPEGXL_PROBE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define FF_JPEGXL_CODESTREAM_SIGNATURE_LE 0x0aff
|
||||
#define FF_JPEGXL_CONTAINER_SIGNATURE_LE 0x204c584a0c000000
|
||||
|
||||
int ff_jpegxl_verify_codestream_header(const uint8_t *buf, int buflen);
|
||||
|
||||
#endif /* AVFORMAT_JPEGXL_PROBE_H */
|
@ -7839,6 +7839,7 @@ static int mov_probe(const AVProbeData *p)
|
||||
if (tag == MKTAG('f','t','y','p') &&
|
||||
( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
|
||||
|| AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
|
||||
|| AV_RL32(p->buf + offset + 8) == MKTAG('j','x','l',' ')
|
||||
)) {
|
||||
score = FFMAX(score, 5);
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user